Docs Menu
Docs Home
/ / /
Mongoid
/

データモデルのコールバックをカスタマイズする

項目一覧

  • Overview
  • サポートされているコールバック
  • ドキュメント コールバック
  • 関連付けコールバック
  • スレッド ローカル変数
  • 詳細情報

このガイドでは、Mongoid モデルにコールバックを実装して、モデル インスタンスのライフサイクルをカスタマイズする方法を学習できます。

コールバックは、Mongoid がオブジェクトのライフサイクルの指定された時点でトリガーするメソッドです。 オブジェクトの状態が変化する前または後に、指定されたアクションを開始できます。

Mongoid は ActiveRecord のコールバックの多くを実装します。 詳しくは、Active レコードのドキュメントの「 コールバック 」を参照してください。

Mongoid は、 ドキュメント モジュールを実装するモデル クラスに対して次のコールバックをサポートしています。

  • after_initialize

  • after_build

  • before_validation

  • after_validation

  • before_create

  • around_create

  • after_create

  • after_find

  • before_update

  • around_update

  • after_update

  • before_upsert

  • around_upsert

  • after_upsert

  • before_save

  • around_save

  • after_save

  • before_destroy

  • around_destroy

  • after_destroy

前述のコールバックの型の詳細については、Rails APIドキュメントの ActiveRecord::コールバック参照を参照してください。

最上位ドキュメントモデルと埋め込みドキュメントモデルの両方でコールバックを実装できます。

注意

コールバック呼び出しの動作

効率の場合、Mongoid は永続化アクションを実行したドキュメントに対してのみコールバックを呼び出します。 この動作により、Mongoid は大規模な階層をサポートし、ドキュメント階層全体でコールバックを呼び出さないことで、最適化されたアトミックな更新を効率的に処理できます。

ドメイン ロジックのコールバックを実装するときは注意してテスト可能性を確保します。これらの設計ではチェーン内のコールバックが実行を停止したときに予期しないエラーにつながる可能性があるためです。 バックグラウンド ジョブのキューアップなど、プログラムの主要機能外の横断的な問題にはコールバックを使用することをお勧めします。

モデル クラスにコールバックを実装して登録する必要があります。 コールバックを登録するには、通常のメソッド、ブロック、Proc オブジェクトを使用するか、クラスまたはモジュールを使用するカスタムコールバックオブジェクトを定義します。

この例では、次の方法で Contact モデルクラスのコールバックを登録する方法を示します。

  • ContactインスタンスがMongoDBに保存される前に process_phone メソッドをトリガーする before_saveクラスメソッドが含まれます。 process_phone メソッドはクラスで個別に定義されます。

  • after_destroyクラスメソッドを含み、Contactインスタンスが削除されたときにブロックを使用してメッセージを出力します。

class Contact
include Mongoid::Document
field :name, type: String
field :phone, type: String
# Creates a callback to clean phone numbers before saving
before_save :process_phone
protected
def process_phone
self.phone = phone.gsub(/[^0-9]/, "") if attribute_present?("phone")
end
# Creates a callback to send a message about object deletion
after_destroy do
p "deleted the contact for #{name}"
end
end

次のコードは、コールバックアクションを示すデータ操作を実行します。

Contact.create(name: 'Serena Atherton', phone: '999 555-3030')
# => `phone` field saved as '9995553030'
Contact.create(name: 'Zayba Haq', phone: '999 123?5050')
# => `phone` field saved as '9991235050'
Contact.first.destroy
# => Console message: "deleted the contact for Serena Atherton"

コールバック機能は Active サポートから取得されているため、コールバックを登録するには代わりに set_callbackクラスメソッド構文を使用できます。 次のコードは、この構文を使用して、aliases 配列の nameフィールドの元の値を保存するコールバックを作成する方法を示しています。

class Contact
include Mongoid::Document
field :name, type: String
field :phone, type: String
field :aliases, type: Array, default: []
set_callback(:update, :before) do |document|
if document.name_changed?
document.push(aliases: document.name_was)
end
end
end
Contact.create(name: 'Xavier Bloom', phone: '4447779999')
Contact.first.update(name: 'Xav - coworker')
# Saved document in MongoDB:
# {"aliases":["Xavier Bloom"],"name":"Xav - coworker","phone":"4447779999"}

Mongoid は、次の関連付けコールバックを提供します。

  • after_add

  • after_remove

  • before_add

  • before_remove

モデルクラスに関連付けコールバックを登録すると、次の関連付けのいずれかからドキュメントを追加または削除するたびに呼び出されます。

  • embeds_many

  • has_many

  • has_and_belongs_to_many

それぞれの関連付けのオプションとして関連付けコールバックを指定します。 追加または削除されたドキュメントを、指定されたコールバックのパラメーターとして渡す必要があります。

次のコードは、複数の SavedArticle インスタンスを埋め込む User モデルクラスに関連付けコールバックを登録して、1 つのインスタンスの埋め込みドキュメント数を制限する方法を示しています。

class User
include Mongoid::Document
field :username, type: String
# Registers the callback in the association statement
embeds_many :saved_articles, before_add: :send_message
protected
# Passes the association document as a parameter to the callback
def send_message(saved_article)
if saved_articles.count >= 10
p "you can't save more than 10 articles at a time"
throw(:abort)
end
end
end
class SavedArticle
include Mongoid::Document
embedded_in :user
field :url, type: String
end

cascade_callbacks: true が設定された関連付けに子ドキュメントを埋め込んでいる場合、埋め込まれた子コールバックはRuby フィルター 内で実行されます。つまり、Thread#[] メソッドと Thread#[]= メソッドを使用してフィルター ローカル変数を取得および設定している場合、それらのコールバックは期待される値の読み取りや設定を行いません。

Thread#thread_variable_getThread#thread_variable_settrue スレッド ローカル変数を取得して設定するには、9.0.3 メソッドと メソッドを使用することをお勧めします。便宜上、Mongoid v では、この機能を実装するために Mongoid::Threaded.get メソッドと Mongoid:Threaded.set メソッドが導入されています。

Mongoid がコールバックを実行中ないようにする方法については、Active レコード ドキュメントの次の参照を参照してください。

Mongoid がトランザクションでコールバックを管理する方法の詳細については、「 トランザクションとセッション のガイド 」を参照してください。

MongoDBデータにアクセスして変更する方法については、「 データの操作 」ガイドを参照してください。

戻る

ドキュメントの検証