更新after_commit
关系并销毁记录时,不会触发has_many
回调。
我有一段感情
class Expertise
has_many :doctor_expertises
has_many :doctor_profiles, through: :doctor_expertises
class DoctorExpertise
belongs_to :doctor_profile
belongs_to :expertise
after_commit :do_something
def do_something
# not called when record destroyed
end
在我的控制器中,我使用以下方法更新has_many
关系
def create
doc = DoctorProfile.find(params[:doctor_id])
doc.expertise_ids = params[:expertise_ids].select do |x|
x.to_i > 0
end
doc.save!
render json: doc.expertises
end
我知道我应该在关系上使用update
和destroy
。但是,为什么after_commit
在被销毁时不会被记录调用?
我猜这与我设置doc.expertise_ids
不触发回调的方式有关。但是,除了简要here之外,我无法找到有关此方法的任何文档。是否有文件证实或否认这种怀疑或是否还有其他事情发生?
答案 0 :(得分:1)
来自您关联的RailsGuides:
自动删除联接模型是直接的,不会触发销毁回调。
虽然它没有说明after_commit,但它很可能也不会被解雇
我认为您正在寻找的答案就在这里:
Howto use callbacks in a has_many through association?
您需要在has_many声明中使用after_remove
答案 1 :(得分:0)
更新联接模型关联后,Rails在集合上添加和删除记录。要删除记录,Rails使用delete
方法,该方法将不会调用任何destroy callback。
解决方案1
添加或删除关联时调用某些回调的一种方法是使用Association Callbacks。
class Expertise
has_many :doctor_expertises
has_many :doctor_profiles, through: :doctor_expertises
before_remove: :my_before_remove,
after_remove: my_after_remove
def my_before_remove(doctor_profile)
...
end
def my_after_remove(doctor_profile)
...
end
end
解决方案2
在删除记录时,Force Rails调用destroy
而不是delete
。
为此,请安装gem replace_with_destroy并将选项replace_with_destroy: true
传递给 has_many 关联。
class Expertise
has_many :doctor_expertises
has_many :doctor_profiles, through: :doctor_expertises,
replace_with_destroy: true
...
end
class DoctorExpertise
belongs_to :doctor_profile
belongs_to :expertise
after_commit :do_something
def do_something
# this will be called when updating Expertise.doctor_profiles
# because use destroyed instead delete to remove the record
end
这样,您可以确保Rails调用所有destroy callbacks。
答案 2 :(得分:0)
像这样添加dependent: :destroy
has_many :doctor_profiles, through: :doctor_expertises, dependent: :destroy
我知道对 has_many 进行依赖销毁有点误导,但它会触发销毁回调并且不会销毁基本记录,只会销毁连接记录。参考:https://github.com/collectiveidea/audited/issues/246