Rails accepts_nested_attributes_ for callbacks

I have two models Ticket and TicketComment , TicketComment is a child of Ticket.

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 

What I want to do is simulate functionality in Trac, where if a user makes changes to a ticket and / or adds a comment, an email is sent to the people assigned to the ticket.

I want to use the after_update or after_save callback so that I know that all the information was saved before sending the email.

How can I detect changes in the model (ticket.changes) and whether or not a new comment (ticket.comments) was created and this update was sent (x changes to y, user comment text is added) in ONE email address in the callback method?

+4
source share
1 answer

you can use ActiveRecord :: Dirty module, which allows you to track unsaved changes.

eg.

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

So, inside before_update before_create you have to do this (you can only check before saving!).

A very nice place to collect all these methods is in the Observer-class TicketObserver, so you can separate your "observer" code from your real model.

eg.

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

in order to include the observer class, you need to add this to your environment.rb :

 config.active_record.observers = :ticket_observer 

This should help you :)

Regarding related comments. If you do this:

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

So that will be exactly what you need. This does not work for you? Remember again: you need to check this before saving, of course :)

I assume that you need to collect data that has been changed in before_create or before_update, and really send mail in after_update / create (because then you are sure that it succeeded).

Apparently, this is not yet clear. I will make it more explicit. I would recommend using the TicketObserver class. But if you want to use a callback, it will be something like this:

 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 
+4
source

Source: https://habr.com/ru/post/1309485/


All Articles