2013-02-10 132 views
0

我正在編寫一個API,並有兩個模型將作爲一個職位的一部分創建,那些是OrderLineItem。我的API期待這種格式(理想)數據:ActiveRecord在保存模型之前驗證範圍關聯?

{ 
    "name": "Test Name", 
    "date": "2013/01/01", 
    "items": [{ 
     "name": "Item One", 
     "quantity": 10 
    }, { 
     "name": "Item Two", 
     "quantity": 30 
    }] 
} 

在上面的例子中,「名」和「日期」是我Order模型的特性,並在「項目」陣列中的每個條目是LineItem 。我的兩個型號定義如下:

class Order < ActiveRecord::Base 
    has_many :line_items 
end 

class LineItem < ActiveRecord::Base 
    belongs_to :order 

    validates :name, :uniqueness => {:scope => :order_id } 
end 

因此,每個訂單項必須是唯一的訂單。當我收到POST請求來構建我的項目時,似乎我無法正確驗證LineItems的唯一性,直到保存我的Order。但是,如果我的LineItem無法驗證,那麼我已經保存了一個我不想在我的系統中執行的命令。

處理這種情況的正確方法是什麼?

回答

1

您要查找的聲音是否在Order.valid時要求驗證訂單項?叫做。你可以用validates_associated做到這一點:

class Order < ActiveRecord::Base 
    has_many :line_items 
    validates_associated :line_items 
end 

這將導致上線項目驗證被稱爲太大。有關詳細信息,請參閱:

http://guides.rubyonrails.org/active_record_validations_callbacks.html#validates_associated

編輯

正如在評論中指出,似乎當前打開的錯誤阻止驗證從失敗的(雖然重複LINE_ITEM不會被保存到磁盤)。請參閱:

爲了解決這個錯誤,你可能想創建一個before_validation回調驗證名的唯一的新項目。一旦錯誤得到解決,您將能夠刪除此回調。

+0

但是,這將與範圍驗證工作?爲了確保Order的作用域的唯一性,Rails將根據order.id生成一個SELECT,以確保數據庫中沒有記錄違反驗證。這會導致問題,因爲訂單還沒有ID。這是不正確的? – 2013-02-10 19:06:45

+0

正確,它似乎有一些開放的錯誤與不檢查內存中的對象。以上將停止重複保存,但不會失敗驗證。我會編輯指出這一點。 – gcastro 2013-02-10 23:01:32