2010-05-11 84 views
4

我有两个模型票务评论,TicketComment是票的孩子。Rails accept_nested_attributes_for回调

ticket.rb

class Ticket < ActiveRecord::Base 
    has_many :ticket_comments, :dependent => :destroy, :order => 'created_at DESC' 

    # allow the ticket comments to be created from within a ticket form 
    accepts_nested_attributes_for :ticket_comments, :reject_if => proc { |attributes| attributes['comment'].blank? } 
end 

ticket_comment.rb

class TicketComment < ActiveRecord::Base 
    belongs_to :ticket 

    validates_presence_of :comment 
end 

我想要做的就是模仿Trac系统,其中,若所述功能一个用户对票证进行更改和/或添加评论,电子邮件将发送给分配给票证的人员。

我想使用after_update或after_save回调,以便我知道信息在发送电子邮件之前全部保存。

如何检测模型(ticket.changes)的更改以及是否创建新评论(ticket.comments)并发送此更新(x更改为y,用户添加了评论'text')在一个电子邮件中的回调方法?

+0

啊哈,我想我误解了你的问题。道歉。我会试着想出一个实际的解决方案。 – 2010-05-11 23:16:17

回答

4

您可以使用ActiveRecord::Dirty模块,该模块允许您跟踪未保存的更改。

E.g.

t1 = Ticket.first 
t1.some_attribute = some_new_value 
t1.changed? => true 
t1.some_attribute_changed? => true 
t1.some_attribute_was => old_value 

所以在before_create的before_update里面你应该这些(你只能在save之前检查!)。

一个收集所有这些方法的好地方是Observer-class TicketObserver,因此您可以将您的“观察者”代码与您的实际模型分开。

E.g.

class TicketObserver < ActiveRecord::Observer 
    def before_update 
    .. do some checking here .. 
    end 
end 

,使观察者级,您需要在您的environment.rb补充一点:

config.active_record.observers = :ticket_observer 

这应该让你开始:)

什么涉及连接的意见。如果你这样做:

new_comment = ticket.ticket_comments.build 
new_comment.new_record? => true 
ticket.comments.changed => true 

因此,这正是你所需要的。这不适合你吗? 再次注意:您需要检查之前保存,当然:)

我想你必须收集在before_create或before_update更改的数据,并在after_update /创建实际发送邮件(因为那么你确定它成功了)。

显然它还不清楚。我会更加明确一些。我会推荐使用TicketObserver类。但如果你想使用回调,它会是这样的:

class Ticked 

    before_save :check_state 
    after_save :send_mail_if_needed 

    def check_state 
    @logmsg="" 
    if ticket_comments.changed 
     # find the comment 
     ticket_comments.each do |c| 
     @logmsg << "comment changed" if c.changed? 
     @logmsg << "comment added" if c.new_record? 
     end 
    end 
    end 

end 
def send_mail_if_needed 
    if @logmsg.size > 0 
    ..send mail.. 
    end 
end 
+0

我已经有脏代码工作,我明白这一部分。这里困难的部分是确定是否创建了TicketComment,它是一个子对象。如果包含一个,我需要添加它的内容..不幸的是,像这样的孩子不会出现在“变化”数组中,因为它不是一个变化(不脏) – Rabbott 2010-05-11 23:52:10

+0

嗨,我相应地扩展了我的答案。现在它更有意义吗? – nathanvda 2010-05-12 08:45:50

+0

是的,我明白这一切..我明白脏。尽管肮脏不帮助我。当提交表单时,在控制器中我有一个散列(params [:ticket]),创建了一个新的ticket_comment,并在该散列中提供。票证对象已保存。 ticket_comment被保存。现在,在回调中,我有SELF,我如何知道添加了评论,以及如何获得该评论? – Rabbott 2010-05-12 15:30:46