我有一个模型,Guest
其中包含的嵌套属性Numberplate
。
Guest
采用STI(单表继承)并从继承Person
。为避免需要额外的查询或加入另一个表,我将人员类型保存person_type
在Numberplate
表中称为字段的地方。这样,我就知道哪些号码牌归来宾所有,而无需与人员表一起加入。
由于此设置,我需要在上手动设置正确person_type
的名称Numberplate
(存在其他人类型)。我将其实现为模型before_validation
上的回调Numberplate
:
before_validation do
self.person_type = self.person.type
end
实际的实现更为通用,但归结为这一点。现在,我将在控制台中创建一个Guest
并Numberplate
在一个调用中,所有这些都将按预期工作:
Numberplate.new({person: Guest.new({company: Company.first}), plate: 'EFEF98'})
在person_type
对Numberplate
实例正确设置"Guest"
。
当我有一个允许嵌套属性在一个请求中创建Guest
和的API端点时,就会出现问题Numberplate
。奇怪的是,person_type
获取的内容"Person'
与"Guest"
预期的一样,而不是预期的。我调试了一下,并person_type
在before_validation
回调中正确设置了gets,但是在该回调和before_save
回调之间,person_type
突然更改为"Person"
。我尝试覆盖person_type
设置器并在设置时记录日志。奇怪的是,没有在两个ActiveRecord回调之间调用设置器。
对于这种行为的引入方式,以及这是否是某个地方的Rails核心中的错误,还是我没有考虑到什么,我感到有些困惑。我当前的解决方法是person_type
在另一个before_save
回调中设置,但这并不是最佳解决方案。
相关型号:
class Guest < Person
accepts_nested_attributes_for :numberplates
end
class Numberplate < ApplicationRecord
before_validation do
self.person_type = self.person.type
end
after_validation do
# person_type is correctly set to "Guest"
puts self.inspect
end
before_create do
# person_type is now suddenly set to "Person"
puts self.inspect
end
end
所以我想通了。
在Person
课堂上我有这个:
has_many :numberplates, as: :person, inverse_of: :person
该as: :person
部分不应存在,并介绍了此行为。它之所以存在是由于较早地从多态性迁移到STI,因此被遗忘了。一旦我删除了所有内容,一切按预期进行。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句