2011-09-01 29 views
0

之前我的模型需要在新行被添加到數據庫中,即使之前的所有時間強制執行的has_many關聯的特定順序。訂購的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 

據我瞭解,在has_many協會:order標誌將通過附加的ORDER BY條款的順序出來的數據庫記錄SQL查詢。然而,就我而言,重要的是組裝中的零件集合必須被命令驗證工作,並且在記錄寫入數據庫之前必須發生。

我已經通過執行以下操作,在軌控制檯這有點實驗:

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集合排序的最佳方法嗎?

回答

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 
+0

執行它,如果我正確理解你的代碼,它是做什麼的查詢數據庫中的整個部件表找那些比更大的任何part_numbers新的part_number被添加,如果是,則將新部件標記爲無效。這不是我想要做的事情。我需要的是與給定裝配關聯的所有零件都按照特定順序排列,以便我的驗證邏輯可以迭代它們並確定裝配的整套零件是否彼此一致。 – Denis

+0

我已經修改了我的答案,以便您正在查看零件的特定裝配。 –

+0

好的,這仍然不是我正在尋找的東西,但我認爲我可以在此基礎上向我的解決方案發展。我認爲我需要做的是將record.assembly.parts集合複製到一個臨時變量,將新部分插入到臨時集合變量中,對臨時集合變量進行排序,然後檢查合法性。我一直在尋找一種內置的方法來排序臨時集合,但到目前爲止我還沒有做任何事情。我想我可以建立我贏得的排序例程,但如果有內置的東西是最好的。 – Denis