質問

2つのモデルを持っています チケット そして チケットコメント, 、TicketComment は 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

チケットコメント.rb

class TicketComment < ActiveRecord::Base
  belongs_to :ticket

  validates_presence_of :comment
end

私がやりたいのは、Trac の機能を模倣することです。ユーザーがチケットに変更を加えたり、コメントを追加したりすると、チケットに割り当てられているユーザーに電子メールが送信されます。

after_update または after_save コールバックを使用して、電子メールを送信する前に情報がすべて保存されたことを確認したいと考えています。

モデルへの変更 (ticket.changes) と新しいコメントが作成されたかどうか (ticket.comments) を検出し、この更新 (x が y に変更、ユーザーがコメント「テキスト」を追加) を 1 つの電子メールで送信するにはどうすればよいですか?コールバックメソッド?

役に立ちましたか?

解決

あなたがすることができますのActiveRecord ::ダーティのモジュールを、使用することができます未保存の変更を追跡します。

例えばます。

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内側にあなたがそれら(あなただけ保存する前に確認することができます!)する必要があります。

は、すべてのこれらのメソッドを収集するためにA非常に素晴らしい場所は、オブザーバークラスであります> TicketObserverので、あなたの実際のモデルから、あなたの「オブザーバー」-codeを区切ることができます。

例えばます。

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
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top