我在我的一个Rails模型中使用accepts_nested_attributes_for,我想在创建父节点后保存子节点.
表单完美无缺,但验证失败.为简单起见,请想象以下内容:
class Project < ActiveRecord::Base
has_many :tasks
accepts_nested_attributes_for :tasks
end
class Task < ActiveRecord::Base
belongs_to :project
validates_presence_of :project_id
validates_associated :project
end
Run Code Online (Sandbox Code Playgroud)
而我正在运行:
Project.create!(
:name => 'Something',
:task_attributes => [ { :name => '123' }, { :name => '456' } ]
)
Run Code Online (Sandbox Code Playgroud)
保存项目模型后,验证失败,因为它们没有project_id(因为项目尚未保存).
似乎Rails遵循以下模式:
模式应该是:
所以我的问题归结为:如何在保存父(项目)之后让Rails运行project_id =(或project =)方法并验证子项(任务),但不保存父项目(项目)如果任何孩子(任务)无效?
有任何想法吗?
我有几个这样的模特
class Bill < ActiveRecord::Base
has_many :bill_items
belongs_to :store
accepts_nested_attributes_for :bill_items
end
class BillItem <ActiveRecord::Base
belongs_to :product
belongs_to :bill
validate :has_enough_stock
def has_enough_stock
stock_available = Inventory.product_is(self.product).store_is(self.bill.store).one.quantity
errors.add(:quantity, "only #{stock_available} is available") if stock_available < self.quantity
end
end
Run Code Online (Sandbox Code Playgroud)
上面的验证显然不起作用,因为当我从bill表单中的嵌套属性中读取bill_items时,属性bill_item.bill_id或bill_item.bill在保存之前不可用.
那我该怎么做呢?
我有一个Rails模型的嵌套属性,并且关联验证由于某种原因失败.我没有使用accepts_nested_attributes_for,但我做的事情非常相似.
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
Run Code Online (Sandbox Code Playgroud)
这是一个人为的例子,但与我想要做的类似.我已经看了一下accepts_nested_attributes_for做了什么,它使用了构建方法,我认为它会将构建的属性与项目相关联.
我还查看了accepts_nested_attributes_for子关联验证失败,这给了我validates_presence_of :unless=>valid?
有关如何使其工作的任何想法?