Question

J'ai deux modèles Ticket et TicketComment , le TicketComment est un enfant de billets.

  

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

Ce que je veux faire est d'imiter la fonctionnalité dans Trac, où si un utilisateur effectue une modification du billet, et / ou ajoute un commentaire, un email est envoyé aux personnes affectées au ticket.

Je veux utiliser un after_update ou after_save rappel, de sorte que je connais les informations ont été tous sauvés avant d'envoyer des e-mails.

Comment puis-je détecter des modifications au modèle (ticket.changes), ainsi que si un nouveau commentaire a été créé ou non (ticket.comments) et envoyer cette mise à jour (x modifications à y, l'utilisateur a ajouté un commentaire « texte ») dans uN email dans une méthode de rappel?

Était-ce utile?

La solution

vous pouvez utiliser le ActiveRecord :: Module Sale , qui vous permet pour suivre les modifications non enregistrées.

par exemple.

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

Alors dans un before_update de before_create vous devriez ceux (vous ne pouvez vérifier avant que l'enregistrement!).

Un endroit très agréable de rassembler toutes ces méthodes se trouve dans une Observer classe TicketObserver, de sorte que vous pouvez séparer votre -code « observateur » de votre modèle actuel.

par exemple.

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

pour permettre à la classe d'observateur, vous devez ajouter dans votre environment.rb:

config.active_record.observers = :ticket_observer

Cela devrait vous aider à démarrer:)

Ce qui concerne les commentaires liés. Si vous faites ceci:

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

Alors, ce serait exactement ce que vous avez besoin. Est-ce que fonctionne pas pour vous? Notez à nouveau: vous devez vérifier avant d'enregistrer, bien sûr:)

Je suppose que vous devez recueillir les données qui ont changé dans un before_create ou before_update, et dans un after_update / créer réellement envoyer le courrier (parce que vous êtes sûr qu'il a réussi).

Apparemment, il est toujours pas clair. Je vais faire un peu plus explicite. Je recommande d'utiliser la classe TicketObserver. Mais si vous voulez utiliser la fonction de rappel, ce serait comme ceci:

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
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top