Railsのコールバックについてまとめてみた
Railsのコールバックとは、一体何なんだろうか。今回は、Railsのコールバックの概要を解説する。
1.コールバックとは何か
Railsのコールバックは、オブジェクトの状態が変わるとき、すなわちオブジェクトが生成、更新、破壊されるときや、バリデーションを実行するときの前後に共通の処理を追加する仕組みである。これはモデル層で指定でき、処理を共通化することによって、モデルの一貫性を保て、またコード量を減らすことができる。
2. 2種類のコールバックの定義の仕方
モデルにて、コールバックを指定する方法は、2つある。
まず、最も一般的な方法がprivateでメソッドを切って、それを呼び出す方法。
class User < ActiveRecord::Base validates :login, :email, presence: true #validationの指定 before_validation :ensure_login_has_a_value #callbackの指定 protected def ensure_login_has_a_value if login.nil? self.login = email unless email.blank? end end end
次に、コールバックにブロックを渡す方法。
class User < ActiveRecord::Base validates :login, :email, presence: true before_create do self.name = login.capitalize if name.blank? end end
さらに、コールバックの定義を、オブジェクトのライフサイクル(オブジェクトの生成、更新、削除等)の中の一部の処理に関してのみ行うことができる。それは、以下のようにonオプションに指定する。
class User < ActiveRecord::Base before_validation :normalize_name, on: :create #createアクションにのみ、コールバックが適用される。 # :on に配列も引き渡せる。 after_validation :set_location, on: [ :create, :update ] protected def normalize_name self.name = self.name.downcase.titleize end def set_location self.location = LocationService.query(self) end end
3. 使用できるコールバック一覧
まず、オブジェクトのライフサイクル、すなわちオブジェクトの生成、更新、削除の各過程において使用可能なコールバックを、呼び出される順番に、以下並べる。
before_validation
↓
after_validation
↓
before_save
↓
around_save
↓
before_create
↓
around_create
↓
after_create
↓
after_save
before_validation
↓
after_validation
↓
before_save
↓
around_save
↓
before_update
↓
around_update
↓
after_update
↓
after_save
before_destroy
↓
around_destroy
↓
after_destroy
・オブジェクトがinitializeされたあと => after_initialize
オブジェクトに対して、newメソッドが呼ばれたときや、データベースからレコードがloadされたとき(データベースのレコードがインスタンス化されたとき)等、オブジェクトがinitializeされた後に処理を追加するコールバック。
・データベースからレコードがloadされたあと => after_find
ただし、after_initializeとafter_findが両方定義されているとき、after_findが先に呼び出される。
class User < ActiveRecord::Base after_initialize do |user| puts "after_initializeを呼び出しました" end after_find do |user| puts "after_findを呼び出しました" end end >> User.new after_initializeを呼び出しました => #<User id: nil> >> User.first after_findを呼び出しました after_initializeを呼び出しました => #<User id: 1>
・オブジェクトにtouchメソッドが呼び出されたあと => after_touch
オブジェクトのupdated_atカラムを現在時刻に更新するtouchメソッドが呼び出されるあとに処理を追加するコールバック。
参照URL:Active Record Callbacks — Ruby on Rails Guides
以上