Rails4中的事务和验证

时间:2014-03-12 22:04:39

标签: validation ruby-on-rails-4 transactions

我遇到了Rails 4和验证问题。让我们考虑一下这个模型:

# 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

父模型Parent has_many :items。这个想法是,每个父母的物品都是有序的;因此,对于每个父母, n 相关项必须具有 0 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似乎不是答案,因为我仍然必须在事务的最后一次调用{/ 1}} 时调用

所以我想在事务中进行几次保存,我希望在提交时验证所有保存。怎么做?

1 个答案:

答案 0 :(得分: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

除此之外 - 我很好奇你为什么不使用&#34;排序!&#34;或者&#34;命令&#34; (使用ORDER BY SQL检索),这将保证订单,无需订购验证。