連載
» 2014年06月30日 18時00分 公開

ActiveRecordにおけるモデルの「関連」とコールバックの使い方開発現場でちゃんと使えるRails 4入門(6)(3/3 ページ)

[著:林慶、監修:山根剛司,株式会社アジャイルウェア]
前のページへ 1|2|3       

モデルオブジェクトに関する特定のイベントが発生した際に実行したい処理を指定しておく「コールバック」

 モデルオブジェクトが保存されるときなど、モデルオブジェクトに関する特定のイベントが発生した際に実行したい処理を「コールバック」として指定しておく仕組みもActiveRecordには用意されています。

コールバックを実行するメソッド

 コールバックが実行されるメソッドでオブジェクトの保存や更新に関わるものを次に挙げます。

  • create
  • create!
  • decrement!
  • destroy
  • destroy_all
  • increment!
  • save
  • save!
  • save(validate: false)
  • toggle!
  • update_attribute
  • update
  • update!
  • valid?

 他にも「all」「find」などのモデルオブジェクトを取得するメソッドのコールバックも用意されています。

コールバックの種類

 前述したオブジェクトの保存などに関わるコールバックには、保存時・更新時・削除時に呼び出されるものがあり、一部では共通となっています。以下に、それらのコールバックを挙げておきます。

  • 新規作成(create)系メソッドと更新(update)系メソッドのコールバック
    • before_validation
    • after_validation
    • before_save
    • around_save
    • before_create(新規作成)/before_update(更新)
    • around_create(新規作成)/around_update(更新)
    • after_create(新規作成)/after_update(更新)
    • after_save
  • 削除(destroy)メソッドのコールバック
    • before_destroy
    • around_destroy
    • after_destroy


コールバックの使い方

 コールバックを使うには、いくつかの方法があります。

  • コールバックメソッドの引数で指定

 コールバックメソッドに処理を行うメソッド名のシンボルを渡すことで使えます。通常は、この方法でコールバックを指定するのが一番よいでしょう。

class Book < ActiveRecord::Base
  after_save :increment_user_books_size
  private
  def increment_user_books_size
    self.user.increment!(:books_size)
  end
end
  • 引数に文字列を指定

 また、処理を記述した文字列を渡しても使えます。

class Book < ActiveRecord::Base
  after_save "self.user.increment!(:books_size)"
end
  • ブロック

 ブロックでも使えます。

class Book < ActiveRecord::Base
  after_save do |record|
    record.user.increment!(:books_size)
  end
end
  • 引数にコールバックのメソッドを持つクラスを指定

 この他にも、各コールバックのメソッドを持つクラスを作り、そのインスタンスを渡すことでもコールバックを使えます。

class User < ActiveRecord::Base
  after_create BooksSizeIncrement.new
end
 
class BooksSizeIncrement
  def initialize()
  end
  
  # 対象のモデルオブジェクトが引数として渡されます
  def after_create(record)
    # 所有者の書籍所持数をインクリメント
    record.user.increment!(:books_size)
  end
end

Rails 4からは外部のgemとなった「ActiveRecord::Observer」

 これと似た「ActiveRecord::Observer」という機能もありましたが、こちらはRails 4からは外部のgemとなりました。

 オブジェクトのイベントをきっかけに実行したい処理がそのオブジェクトを主体として扱わないような場合には、そちらを使うとよいでしょう。

次回からは、コントローラーを支える技術について

 ActiveRecordの機能は多岐にわたり、本連載で紹介した機能はほんの一部にすぎません。しかし、ドキュメントも非常に豊富なため、実現したい機能があれば調べてみると案外すぐ出てくるかもしれません。

 またモデルではアプリケーションのロジックを担うことが多いため、「rails console」などでトライ&エラーを繰り返しながら機能を作っていくことが多くなると思います。そこで「rails console」を使いやすくするgemなどを探してみるのもよいでしょう。

 次回からはコントローラーを支える技術についての解説です。頑張っていきましょう。

著者プロフィール

林 慶(Rails技術者認定シルバー試験問題作成者)

平成2年大阪生まれ。2006年から高専で情報工学を学んでいたが当時は所謂プログラミングができない工学生だった。卒業後、高専の専攻科に上がったもののマンネリ化したキャンパスライフに飽きたため休学して渡豪。そこでプログラミングに対するコンプレックスを克服するためにRuby on Railsなどでアプリケーションを作ることを覚える。

帰国後から現在までは復学し推薦システムに関する研究を行いながら、アジャイルウェアでRuby on Railsアプリケーションの開発業務に従事している。

好きなメソッドはinject。


監修者プロフィール

山根 剛司(Ruby業務開発歴7年)

兵庫県生まれ。1997年からベンチャー系のパッケージベンダーで10年間勤務。当時、使用していた言語はJavaとサーバーサイドJavaScript。

2007年よりITコンサル会社に転職し、Rubyと出会って衝撃を受ける。基幹システムをRuby on Railsで置き換えるプロジェクトに従事。それ以来Ruby一筋で、Ruby on Railsのプラグインやgemも開発。

2013年より、株式会社アジャイルウェアに所属。アジャイルな手法で、Ruby on Railsを使って企業向けシステムを構築する業務に従事。

Ruby関西所属。好きなメソッドはtap。

Twitter:@spring_kuma、Facebook:山根 剛司


前のページへ 1|2|3       

Copyright © ITmedia, Inc. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。