2010-01-20 78 views
4

我有Rails模型的嵌套屬性,由於某種原因,關聯驗證失敗。我沒有使用accept_nested_attributes_for,但我做的事情非常相似。Rails嵌套屬性關聯驗證失敗

class Project < ActiveRecord::Base 
    has_many :project_attributes 

    def name 
    project_attributes.find_by_name("name") 
    end 

    def name=(val) 
    attribute = project_attributes.find_by_name("name") 

    if attribute 
     attribute.value = val 
    else 
     project_attributes.build(:name=>"name", :value=>val) 
    end 
    end 
end 

class ProjectAttribute < ActiveRecord::Base 
    belongs_to :project 

    validates_presence_of :name 
    validates_uniqueness_of :name, :scope => :project_id 

    validates_presence_of :project_id, :unless => lambda {|attribute| attribute.project.try(:valid?)} 
    validates_associated :project 

end 

這是一個人爲的例子,但類似於我想要做的。我看了一下什麼是accept_nested_attributes_for,它使用了構建方法,我認爲這會將構建的屬性與項目相關聯。

我又看了看accepts_nested_attributes_for child association validation failing這給了我如何得到這個工作的validates_presence_of :unless=>valid?

任何想法?

+0

我試着改變它以使用accep_nested_attributes_for並且運行到相同的問題。在validates_presence_of中:project_id調用'project'返回nil。 – 2010-01-20 18:09:28

回答

5

validates_associated看起來比它的價值更麻煩。如果您刪除了validates_presence_of:project_id,則您的示例可以正常工作。這是一個黑客的例子,恢復驗證(發現說明here)。

class ProjectAttribute < ActiveRecord::Base 
    belongs_to :project 

    validates_presence_of :name 
    validates_uniqueness_of :name, :scope => :project_id 

    validates_presence_of :project_id, :unless => Proc.new { |project_attribute| 
    project = project_attribute.project 
    ObjectSpace.each_object(Project) {|o| project = o if o.project_attributes.include?(project_attribute)} unless project 
    project 
    } 
end 
-1

只需在project_id上添加非null約束,並讓它在發生時髦事情時發生爆炸。哦,並確保您的測試覆蓋率也不錯。