2012-05-27 18 views
2

在我的应用程序有以下关系:如何获取我对象的相关属性的BEFORE和AFTER状态?

Document has_and_belongs_to_many Users 
User has_and_belongs_to_many Documents 

什么,我试图找出是如何执行以下操作: 比方说,一个文件有属于它3个用户。如果在更新后他们成为前。 4,我想发送一封电子邮件 消息(document_updated)给第3个,另一封电子邮件(document_assigned)给第4个。

所以我必须知道属于我的Document BEFORE和AFTER文档更新发生的用户。

我的方法迄今已创建一个这样的观察:

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的机会渺茫,因为我猜它是动态地轨道通过填充has_and_belongs_to_many关系。

所以我的问题是:

如何让我的所有相关用户之前更新发生?

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

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

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

感谢

乔治

红宝石1.9.2p320

的Rails 3.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 
+0

感谢。然而,这种按用户粒度方法解决了部分问题。 我可以有效地把所有的“document_assigned”的电子邮件这种方式(内部do_stuff),但如果两个用户在同一时间 增加(为前U4和U5)。然后: 1. document_assigned U4的电子邮件将有没有办法告诉他,u5也被分配到 2。我仍然无法找到他们(并且只有他们)收到“document_updated”电子邮件的初始用户。 (在do_stuff中发送“document_updated”将导致多个电子邮件被发送,在Observer内部发送它也将包括新添加的用户) – sgouros

+0

可能没有完全内置的东西来做到这一点 - 我已经给出了一种替代方法 –