我有一個模型,Guest
這需要嵌套屬性爲Numberplate
嵌套屬性創建變化關聯類型屬性。模型before_validation之間和before_save
Guest
採用STI(單表繼承)和從Person
繼承。爲了防止需要額外的查詢或加入到另一個表格,我將該人員類型保存在Numberplate
表中名爲person_type
的字段中。這樣,我就知道哪些Numberplates由Guests擁有,而無需加入Person表。
由於這種設置,我需要手動設置person_type
在Numberplate
(還有另一種人類型)。我實現了這個爲before_validation
回調的Numberplate
型號:
before_validation do
self.person_type = self.person.type
end
實際的實現是有點更通用的,但它歸結爲這一點。 現在我會在控制檯預期創造一個呼叫Guest
和Numberplate
這一切工作:對Numberplate
實例
Numberplate.new({person: Guest.new({company: Company.first}), plate: 'EFEF98'})
的person_type
正確設置爲"Guest"
。
當我有一個API端點允許嵌套屬性在一個請求中創建Guest
和Numberplate
時,會出現此問題。奇怪的是,隨着預期person_type
被存儲爲"Person'
,而不是"Guest"
。我調試了一下,在person_type
得到的before_validation
回調,但該回調和before_save
回調person_type
突然改變"Person"
之間設置正確。 我試圖覆蓋person_type
setter並在設置時記錄日誌。奇怪的是setter沒有在2個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
請嘗試使用[關聯回調](http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html#module-ActiveRecord:Associations::ClassMethods-label-Association+callbacks)。 – max
@Max剛剛試過,顯示同樣的行爲 – edwardmp
東西被設置person_type列的人,即使沒有在我身邊的任何自定義代碼。奇怪的。 – edwardmp