在使用.build创建对象时,Rails会跳过has_many关联的验证
我需要帮忙弄清楚为什么我的验证被忽略了:
我有以下模型...
一个 Headword,可以包含多个 HeadwordDefinition:
class Headword < ApplicationRecord
has_many :definitions, class_name: 'HeadwordDefinition', foreign_key: 'headword_id', dependent: :destroy, inverse_of: 'headword'
accepts_nested_attributes_for :definitions
validates_associated :definitions
# ...
end
以及相应的 HeadwordDefinition:
class HeadwordDefinition < ApplicationRecord
belongs_to :headword, class_name: 'Headword'
validates :content, uniqueness: true
validates :order, uniqueness: true
# ...
end
当我使用 .build 方法按如下方式创建一个 Headword,并建立它的 HeadwordDefinition 关系时:
red = Headword.new(title: 'wouj')
red.definitions.build([{content: 'bugs', order: 1}, {content: 'bugs', order: 1}])
red.save!
对于 HeadwordDefinition 的验证(在本例中是content与 order的唯一性)被完全忽略了!
可以请你帮我找出原因吗?
解决方案
在验证阶段,这两个 HeadwordDefinition 记录都尚未写入数据库。Rails的唯一性验证只检查已持久化的记录,而不会检查一起保存的多个新相关记录之间的重复。
因此验证确实在运行,但它在向数据库提问那些看不到尚未保存的重复同级的情况,Rails实际上是这样处理的:
-
验证第一条定义:
-
数据表中是否已经存在content = 'bugs' 的行?
-
否!
-
验证第二条定义:
-
数据表中是否已经存在content = 'bugs' 的行?
-
否!(因为第一条定义也未保存)
-
父对象和子对象被视为有效
- Rails将它们保存
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。