こんにちは、鈴木です。
今回は Rails のオブザーバの話をします。
オブザーバとは
Rails のオブザーバとは、デザインパターンの Observer パターンを実現する仕組みです。
可能なことはコールバックと同じで、バリデーションやデータベースへの保存が行われるタイミングで行う処理を記述することができます。
コールバックとオブザーバのどちらを利用するかは、その処理がモデルの一貫性を保つために必要であるかという基準で考えると良いでしょう。
保存前に入力されたパスワードをハッシュ化するのであればコールバック、会員登録後に登録完了メールを送信するような場合はオブザーバが適しています。
オブザーバの作成
オブザーバは以下のような ActiveRecord::Observer を継承したクラスです。
1 2 3 |
class UserObserver < ActiveRecord::Observer end |
ソースファイルは app/models 以下に保存します。
scaffold を利用するのであれば、以下のコマンドでオブザーバを作成できます。
1 |
rails generate observer <モデル名> |
例えば、User モデルのオブザーバを作成するのであれば、以下のコマンドを実行します。
1 |
rails generate observer User |
実行すると、app/models/user_observer.rb が作成されます。
オブザーバの実装はコールバックと同じで、before_save や after_create などのメソッドを定義します。
以下のような感じです。
1 2 3 4 5 6 7 8 9 10 11 |
class UserObserver < ActiveRecord::Observer def after_create(user) # ... ユーザが作成 (= 会員登録) されたので, 登録完了メールを送る. end def after_destroy(user) # ... ユーザが削除 (= 退会) されたので, 個人情報に関するデータを削除する. end end |
何らかの事情でモデルとオブザーバの名前を合わせることができない場合は、以下のように observe メソッドで対象とするモデルを指定することができます。
1 2 3 4 5 6 7 |
class MemberObserver < ActiveRecord::Observer observe :user ... end |
オブザーバの設定
作成したオブザーバを有効にするには、config/application.rb で指定する必要があります。
1 |
config.active_record.observers = [:user_observer] |
実行環境によってオブザーバの有効/無効を切り替えたい場合は、config/environments 以下の環境ごとの設定ファイルに記述します。
複数のモデルを対象とするオブザーバ
複数のモデルに対して、同じオブザーバを設定したい場合があります。
例えば、ブログ記事や商品購入履歴などのモデルがあるとします。
1 2 3 4 5 6 7 8 9 |
# ブログ記事. class Article < ActiveRecord::Base ... end # 商品購入履歴. class Purchase < ActiveRecord::Base ... end |
そして、これらのオブジェクトが登録されたとき (= ブログ記事の投稿や商品を購入したとき) にポイントを付与するオブザーバを作成する場合は、以下のように observe メソッドで対象とするモデルを指定します。
1 2 3 4 5 6 7 8 9 10 |
# ユーザの特定の行動に対してポイントを付与するオブザーバ. class PointingObserver < ActiveRecord::Observer observe :article, :news def after_create(object) # ... ユーザにポイントを付与する. end end |
こうすることで、一つのオブザーバを複数のモデルに結び付けることができます。
まとめ
今回はオブザーバの話をしました。
コールバックとオブザーバはどちらも同じことができますので、どちらを使うべきか見極めた上で活用しましょう。