вы можете использовать модуль ActiveRecord :: Dirty , который позволяет отслеживать несохраненные изменения.
* 1005 Е.Г. *
t1 = Ticket.first
t1.some_attribute = some_new_value
t1.changed? => true
t1.some_attribute_changed? => true
t1.some_attribute_was => old_value
Так что внутри before_update before_create вы должны это сделать (вы можете проверить только перед сохранением!).
Очень хорошее место для сбора всех этих методов - класс наблюдателя TicketObserver, так что вы можете отделить свой код "наблюдателя" от вашей реальной модели.
* 1014 Е.Г. *
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 / create фактически отправлять почту (потому что тогда вы уверены, что это удалось).
Видимо, все еще не ясно. Я сделаю это немного более явным. Я бы порекомендовал использовать класс 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