如何获取对象相关属性的BEFORE和AFTER状态?

时间:2012-05-27 08:21:38

标签: ruby-on-rails

在我的申请中,我有以下关系:

Document has_and_belongs_to_many Users
User has_and_belongs_to_many Documents

我想弄清楚的是如何执行以下操作: 让我们说一个文档有3个属于它的用户。如果更新后他们成为前任。 4,我想发一封电子邮件 消息(document_updated)到第3个,另一个电子邮件消息(document_assigned)到第4个。

所以我必须知道文档更新发生之前和之后属于我的文档的用户。

到目前为止,我的方法是创建一个像这样的观察者:

class DocumentObserver < ActiveRecord::Observer

  def after_update(document)
    # this works because of ActiveModel::Dirty
    # @old_subject=document.subject_was    #subject is a Document attribute (string)

    # this is not working - I get an 'undefined method' error 
    @old_users=document.users_was   

    @new_users=document.users.all.dup

    # perform calculations to find out who the new users are and send emails....
  end
end

我知道@old_users获取有效值的机会很小,因为我猜它是由rails通过has_and_belongs_to_many关系动态填充的。

所以我的问题是:

如何在更新发生之前获取所有相关用户?

(到目前为止,我已尝试过其他一些事情:)

一个。在DocumentController :: edit中获取document.users.all。这将返回一个有效的数组,但我不知道如何将此数组传递给 DocumentObserver.after_update为了执行计算(只是在DocumentController中设置一个实例变量当然不起作用)

B中。试图在DocumentObserver :: before_update中保存document.users。这也不起作用。我仍然获得新的用户值

提前致谢

乔治

Ruby 1.9.2p320

Rails 3.1.0

1 个答案:

答案 0 :(得分:0)

您可以使用before_add回调

class Document
  has_and_belongs_to_many :users, :before_add => :do_stuff

  def  do_stuff(user)
  end
end

当您向文档添加用户时,将调用回调,此时self.users仍会包含您要添加的用户。

如果您需要更复杂的东西,在文档

上使用set_users方法可能更简单
def set_users(new_user_set)
  existing = users
  new_users = users - new_user_set
  # send your emails
  self.users = new_user_set
end