在尝试同时创建父母和孩子时,我遇到了困难。 我认为当关联的父级无法保存时,应该引发异常,但它没有。
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的行为方式。
答案 0 :(得分:1)
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!
答案 1 :(得分:1)
为什么会引发异常?您正在设置parent
,就child
而言,parent
存在(通过验证)并且它不会调用父级和IMO上的create!
也不应该。
您的解决方法是在parent_id
而不是parent
上进行验证,或通过parent.children.create!
创建子项。如果父级未持久化,后者将引发ActiveRecord::RecordNotSaved: You cannot call create unless the parent is saved
答案 2 :(得分:0)
将孩子改为
class Child < ApplicationRecord
belongs_to :parent
validates_presence_of :parent, :id
end
正如@AbM所说,你应该把约束放在某些字段上,这会给你ActiveRecord::RecordInvalid: Validation failed: Id can't be blank
例外。