5

私はTicketTicketCommentの2つのモデルを持っています。TicketCommentは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

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

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

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

4

1 に答える 1

4

ActiveRecord::Dirtyモジュールを使用すると、保存されていない変更を追跡できます。

例えば

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 内では、それらを使用する必要があります (保存前にのみ確認できます!)。

これらすべてのメソッドを収集するのに最適な場所は、Observer クラスのTicketObserver にあるため、実際のモデルから「オブザーバー」コードを分離できます。

例えば

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
于 2010-05-11T23:46:25.360 に答える