在保存到数据库之前订购has_many集合以进行验证

时间:2011-09-01 12:04:12

标签: ruby-on-rails activerecord sql-order-by validation

我的模型需要在新行添加到数据库之前始终强制执行has_many关联的特定排序。

假设我有一个has_many / belongs_to关联,如下所示:

    class Assembly < ActiveRecord::Base
      has_many :parts, :order => "part_number ASC"
    end

    class Part < ActiveRecord::Base
      belongs_to :assembly
    end

据我了解,:order关联上的has_many标志将通过在SQL查询中附加ORDER BY子句来对从数据库中出来的记录进行排序。但是,在我的情况下,同样重要的是订购Assembly中的零件集合以使验证工作,并且即使在将记录写入数据库之前也必须发生这种情况。

我通过执行以下操作在rails控制台中对此进行了一些实验:

a = Assembly.new
p1 = Part.new( :part_number => 2 )
p2 = Part.new( :part_number => 1 )

a << p1    #p1 is added first but should be in second place in collection
a << p2    #p2 is added second but should be in first place in collection

a.parts[0]    #expecting to see part_number=1 but I still get part_number=2

因此,新程序集对象的验证例程将不起作用。在写入数据库之前,有人可以推荐强制执行has_many集合排序的最佳方法吗?

1 个答案:

答案 0 :(得分:0)

您必须在Part型号

强制执行此操作
class Part
  validates_each :part_number, :on => :create do |record, attr, value|
    # if there is already a part number higher than the current part number
    if record.assembly.parts.exists?(
         :conditions => ["part_number >= ?", record.part_number])
      record.errors.add attr, 'missing part number sequence.' 
    end
  end
end