2014-03-12 82 views
0

我有一個Rails 4和驗證問題。讓我們考慮一下這款機型:交易和驗證Rails4

# has integer attribute 'order' 
class Item < ActiveRecord::Base 
    belongs_to :parent, 
    validate :orders_must_be_sequence 

    def orders_must_be_sequence 
    orders = [] 
    parent.items.each do |i| 
     orders << i.order 
    end 
    orders.sort! 
    errors.add :order, "is not in a decent order" if orders != (0..orders.length - 1).to_a 
    end 
end 

有一個父模型Parenthas_many :items。這個想法是,每個父母的項目都是有序的;因此對於每個父母,相關項目必須具有訂單屬性至n-1。這通過驗證orders_must_be_in_sequence驗證。

現在問題所在: 爲了重新排序項目,item必須保存。我的想法是,要做到這一點像一個交易:

ActiveRecord::Base.transaction do 
    item1.order = 2 
    item2.order = 3 
    item3.order = 1 
    item1.save 
    item2.save 
    item3.save 
end 

但隨後save失敗,因爲失敗的驗證。另外validate: false似乎不是答案,因爲我仍然不得不調用save在交易中的最後一次驗證。

所以我想在事務中做一些保存,我希望所有的保存都在提交時進行驗證。這個怎麼做?

回答

1

你可能會改變驗證邏輯,以便爲到父本身,例如: - !「排序」

比這
ActiveRecord::Base.transaction do 
    parent.item1.order = 2 
    parent.item2.order = 3 
    parent.item3.order = 1 
    parent.save 

end 

class Item < ActiveRecord::Base 
    belongs_to :parent 

end 

class Parent < ActiveRecord::Base 
    has_many :item 

    validate :orders_must_be_sequence 

    def orders_must_be_sequence 
    orders = [] 
    parent.items.each do |i| 
     orders << i.order 
    end 
    orders.sort! 
    errors.add :order, "is not in a decent order" if orders != (0..orders.length - 1).to_a 
    end 
end 

其他我很好奇,爲什麼你不只是使用或「訂單」(使用ORDER BY SQL進行檢索),這將保證訂單,避免訂購驗證。

+0

我不這樣認爲,這將起作用,因爲重新排序項目時甚至不會觸摸父對象。 – contradictioned