コールバック

  • コールバックは、ActiveRecordでの検索や更新のタイミングで実行されるメソッドのこと
    • before_validationだったら、バリデートの直前に実行される
    • validationの他に、save/create/update/destoryで、before/afterのメソッドがある
    • find/initalizaでは、afterのみ
    • 当然、deleteでは実行されないので注意!
  • コールバックの基本は、コールバックメソッドで使用するプライベートメソッド名を登録する
    • 以下の場合は、after_destroyにhistory_bookを登録する場合ね
      class Book < ActiveRecord::Base
       after_destroy :history_book
      
       private 
       def history_book
         logger.info('deleted: ' + self.inspect)
       end
      
      • というか、inspect便利だなぁ…
    • これで、こんな感じのログが出る
      deleted: #<Book id: 24, isbn: "978-4-7980-2812-0", title: "タイトル", price: 100, publish: "出版社B", published: "2011-12-17", cd: false, created_at: "2011-12-17 00:03:15", updated_at: "2011-12-17 00:03:15">
      
  • 単なるプライベート以外の定義もできる
    • ブロック形式で直接定義
      class Book < ActiveRecord::Base
       after_destroy do |b|
         logger.info('deleted: ' + self.inspect)
       end
      
      • ちょっとしたコードなら、これが一番楽そう。
    • コールバッククラスを定義
      • まずは、こんなコールバッククラスを作る(app/models/book_callbacks.rb)
        class BookCallbacks
         cattr_accessor :logger       # この中でloggerクラスを直接使えないので、
         self.logger ||= Rails.logger # Railsのloggerを取得して使ってる
        
         def after_destroy(b)
           logger.info('deleted: ' + b.inspect)
         end
        end
        
      • で、作ったコールバッククラスを登録
        class Book < ActiveRecord::Base
         after_destroy BookCallbacks.new
        
      • 共通化は、これがいいのかな?
    • オブザーバーとして定義
      • コールバックだとモデルに対して登録するしか無いけど、オブザーバーなら設定ファイルで着脱可能
      • 要するにコールバックはモデルのデータに対しての処理を書き、オブザーバーはモデル操作のタイミングで行うべき処理を書くらしい
      • 使い方は、まずオブザーバーのクラスをrailsコマンドで生成(この場合はBookに対してのオブザーバーを生成)
        C:\user\dev\railbook\app>rails g observer Book
             invoke  active_record
             create    app/models/book_observer.rb
             invoke    test_unit
             create      test/unit/book_observer_test.rb
        
      • で、生成されたBookObserverクラスに、こんな感じでメソッドを追加
        class BookObserver < ActiveRecord::Observer
         cattr_accessor :logger       # この中でloggerクラスを直接使えないので、
         self.logger ||= Rails.logger # Railsのloggerを取得して使ってる
        
         def after_save(b)
           logger.info('saved: ' + b.inspect)
         end
        end
        
      • あとは、設定ファイル(config/environments/development.rb)に、以下の設定を追加
        Railbook::Application.configure do
         config.active_record.observers = :book_observer
        
      • で、あとは、WEBrickを再起動すれば「saved」のログが出るようになる!
      • ほんとは、オブザーバーではデータソースに関わらない処理を書くので、ここではログを書くべきじゃないよ!通知メール送信とかが正しい感じ

-
最終更新:2011年12月22日 07:25