2010-05-11 111 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

相關問題