具有has_many关联的Active Record回调

时间:2017-06-07 18:13:16

标签: ruby-on-rails-4 activerecord callback associations has-many

每次将子对象添加到父对象(has_many association)时,我想运行before_saveafter_add回调。在回调中,我想根据所有子(课程)的end_date属性在父(同类群组)上设置end_date属性。

class Cohort < ActiveRecord::Base
  has_many :courses   
  before_save :update_end_date

  def update_end_date
    self.end_date = courses.order(:end_date).last.try(:end_date)
  end
end

我遇到的问题是这些课程尚未在before_save回调中保留到数据库,因此courses.order(:end_date)不会返回新添加的课程。

我可以使用几种解决方法(例如使用Ruby courses.sort_by方法或after_save使用update),但我的印象是使用Active Record order如果可能,方法在效率和最佳实践方面将是更可取的。有没有办法在before_save中使用Active Record执行此操作,或者可能是最佳实践?这似乎会出现很多问题,但我很难找到适合我的解决方案,所以我觉得我必须考虑错误。谢谢!

1 个答案:

答案 0 :(得分:0)

如果他们的结束日期晚于队列结束日期,您可以在可以更新队列的课程之后进行保存。并且在课程结束后,告诉队列更新其结束日期以对应剩余的课程。

class Course < ActiveRecord::Base
  belongs_to :cohort
  after_save :maybe_update_cohort_end_date
  after_destroy :update_cohort_end_date

  def maybe_update_cohort_end_date
    if cohort && self.end_date > cohort.end_date
      cohort.end_date = self.end_date
      cohort.save
    end
  end

  def update_cohort_end_date
    cohort.update_end_date if cohort
  end
end

class Cohort < ActiveRecord::Base
  has_many :courses

  def update_end_date
    self.end_date = courses.order(:end_date).last.try(:end_date)
  end
end

这样,只有新课程或更新课程的结束日期会更改同类群组结束日期时,您才会进行更新。但是如果删除了一个课程,还要检查结束日期应该是什么