我有以下型号:
class Course < ApplicationRecord
belongs_to :super_course, inverse_of: :courses
...
end
class SuperCourse < ApplicationRecord
has_many :courses, dependent: :nullify, inverse_of: :super_course
...
end
这两个模型之间的相互关系如下:SuperCourse
将大量具有特定条件的Course
分组。事实是,在后台我可以更改SuperCourse
的{{1}},而我不想有空的Course
(即没有{{ 1}})。
我一直想做的是向SuperCourse
模型添加一个Course
回调,以便它检查以前的after_update
现在是否没有{{1 }}相关联,但我不知道这是否是最佳解决方案(AFAIK,不建议使用回调)。根据{{3}}中的回复,这就是我现在得到的:
Course
但是当我对此进行测试时,我什至没有得到想要的东西。这是失败的SuperCourse
代码段:
Course
这是我最好的选择吗?如果是这样,我该如何运作?如果没有,什么是最佳选择?
谢谢大家!
答案 0 :(得分:0)
我正在做更多的工作,并且在使用Rails 5.1时(由于https://stackoverflow.com/a/20657833/7023504),我得到了回调的工作代码:
def destroy_empty_super_course
id = saved_changes[:super_course_id]&.first
return unless id
super_course = SuperCourse.find(id)
super_course.destroy if super_course.courses.empty?
end
在将let
更改为let!
之后,测试开始通过!无论如何,我仍然想知道这是否是这种情况的最佳解决方案,但至少我有一些有用的方法:)
答案 1 :(得分:0)
回调是此解决方案唯一可行的解决方案,尽管为了更优雅和与Rails风格保持一致,通常为此目的使用around回调。
您的版本失败的原因是因为after_update回调是在提交更新后发生的,因此*_changed?
和*_was
方法并不知道保存之前记录中的脏更改。要获得可以在回调之前完成保存之前的时间段中的数据-它允许执行保存以产生块,从而使yield
语句之前的脏更改可用,实际上在保存之后并在yield
之后的语句中更新逻辑。
def destroy_empty_super_course
return unless super_course_id_changed?
id = super_course_id_was
yield
super_course = SuperCourse.find(id)
super_course.destroy if super_course.courses.empty?
end