My models need to enforce a particular ordering of a has_many association at all times even before new rows get added to the database.
Suppose I have a has_many/belongs_to association as follows:
class Assembly < ActiveRecord::Base
has_many :parts, :order => "part_number ASC"
end
class Part < ActiveRecord::Base
belongs_to :assembly
end
As I understand it, the :order
flag on the has_many
association will order the records coming out of the database by appending an ORDER BY
clause to the SQL query. However, in my case, it is also important that the parts collection in Assembly be ordered for the validation to work and that has to happen even before the records get written to the database.
I've experimented with this a little in the rails console by doing the following:
a = Assembly.new
p1 = Part.new( :part_number => 2 )
p2 = Part.new( :part_number => 1 )
a << p1 #p1 is added first b开发者_StackOverflow社区ut 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
Consequently, the validate routine for the new assembly object would not work. Can somebody recommend the best way to enforce ordering of the has_many collection before writing to the database?
You have to enforce it at the Part
model
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
精彩评论