更新关联记录时为空,销毁has_many关系

时间:2019-05-05 14:58:06

标签: ruby-on-rails ruby activerecord

我有以下型号:

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

这是我最好的选择吗?如果是这样,我该如何运作?如果没有,什么是最佳选择?

谢谢大家!

2 个答案:

答案 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