在尝试同时创建父母和孩子时,我遇到了困难。我认为当关联父节点无法保存时应该引发异常,但事实并非如此。
class Child < ApplicationRecord
belongs_to :parent
validates_presence_of :parent, :name
end
class Parent < ApplicationRecord
has_one :child
validates_presence_of :name
end
请注意,子项保存,并且他们无法查看父项的保存问题:
parent = Parent.new
parent.valid? # => false
child = Child.create!(name: 'something', parent: parent) # => true
child.parent_id # => nil
child.reload.valid? # => false
已创建无效的子项。为什么create!
方法不会在父级上调用create!
,因此会引发异常?
值得注意的是,当遵循相同的过程,而是从父母开始,我们得到了我期望的行为:
child = child.new
child.valid? # => false
parent = Parent.create!(name: 'something', child: child) # => ActiveRecord::Exception
parent.valid? # => false
我知道一些工作(例如关于孩子的validates_associated :parent
),但我试图理解为什么Rails的行为方式。
Rails不知道你是在试图同时保存它们。如果你想同时保存它们,试试nested attributes。
我希望这可以做你想要的:
class Child < ApplicationRecord
belongs_to :parent
validates_presence_of :parent
end
class Parent < ApplicationRecord
has_many :children
validates_presence_of :name
accepts_nested_attributes_for :children, allow_destroy: true
end
parent = Parent.new children: [child]
parent.save!
为什么要提出例外?您正在设置parent
并且就child
而言,parent
存在(通过验证)并且它不会在父母和IMO上调用create!
也不应该。
你的解决方法是验证parent_id
而不是parent
或通过parent.children.create!
创建孩子。如果父母不坚持,后者将提高ActiveRecord::RecordNotSaved: You cannot call create unless the parent is saved
改变孩子
class Child < ApplicationRecord
belongs_to :parent
validates_presence_of :parent, :id
end
正如@AbM所说,你应该把约束放在某个字段上,这会给你ActiveRecord::RecordInvalid: Validation failed: Id can't be blank
异常。