模型关联更新前后

时间:2014-08-10 01:30:38

标签: ruby-on-rails ruby activerecord

假设我有一个Rails模型,我想在更新之前和之后获取关联列表的状态,以查看它们之间的区别。我该怎么做呢?我曾经尝试过只做一个before_update和after_update回调来维护一个关联数组并拒绝更新后数组中的内容与更新之前相比,但似乎我的数组永远不会匹配更新前的状态。

有什么想法吗?

# == Schema Information
#
# Table name: lectures
#
#  id               :integer          not null, primary key
#  organization_id  :integer
#  training_type_id :integer
#  name             :string(255)
#  description      :text
#  start_date       :date
#  end_date         :date
#  training_method  :string(255)
#  trainer_name     :string(255)
#  trainer_phone    :string(255)
#  trainer_email    :string(255)
#  location         :string(255)
#  total_seats      :integer
#  available_seats  :integer
#  hours            :integer
#  created_at       :datetime
#  updated_at       :datetime
#

class Lecture < ActiveRecord::Base

  # # # # # # # # # # # # # # #
  # Relations
  # # # # # # # # # # # # # # #

  belongs_to :organization

  belongs_to :training_type
  has_many :training_histories
  has_many :users, through: :training_histories

  # belongs_to :training_type

  # has_many :training_histories, inverse_of: :lecture, :autosave => true

  accepts_nested_attributes_for :training_histories

  # # # # # # # # # # # # # # #
  # Validations
  # # # # # # # # # # # # # # #

  validates :name,
            :start_date,
            :end_date,
            :location,
            :organization,
            :trainer_email,
            :trainer_name,
            :hours,
            :presence => :true

  validate :start_must_be_before_end_date

  validates :trainer_email, email: true

  after_update :email_users_about_update, email_supervisors_about_signup

  def start_must_be_before_end_date
    errors.add(:start_date, "must be before end date") unless self.start_date <= self.end_date
  end

  def email_users_about_update
    self.training_histories.each do |history|
      UserMailer.updated_training_email(history.user, self).deliver unless history.completed
    end
  end

  def email_supervisors_about_signup
    binding.pry
    if self.users.changed?
      users_dif = self.users - self.users_was
      unless users_dif.nil?
       users_dif.each do |user|
       UserMailer.create_subordinate_training_sign_up(user.leader, user, self).deliver
       end
      end
    end
  end
end

1 个答案:

答案 0 :(得分:0)

您可以使用after_add回调:

# add the callback to our association
has_many :users, through: :training_histories, after_add: :invite_to_training

# this method gets called when a user is added
private
def invite_to_training(user)
  UserMailer.create_subordinate_training_sign_up(user.leader, user, self).deliver
end

有关关联回调的详细信息,请参阅:http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html#module-ActiveRecord::Associations::ClassMethods-label-Association+callbacks