永続性設定
項目一覧
Overview
このガイドでは、Mongoid がデータベースとコレクション内のデータを保持する方法について学習できます。永続性構成とは、Mongoid がMongoDBにデータを保存する方法を制御する設定を指します。これには、モデルクラスのドキュメントが保存されているクライアント、データベース、およびコレクション(read preference)や書込み設定(write preference)などのその他の構成オプションが含まれます。このガイドでは、モデルクラスの永続構成にアクセスして更新するために使用できるメソッドと例を提供します。
注意
「クライアント」タームは、mongoid.yml
ファイル内の clients
の下に定義されたホスト構成を指します。ほとんどのアプリケーションは default
という名前の単一のクライアントを使用します。
デフォルトのコレクション名
デフォルトでは 、Mongoid は、名前が表クラス名の複数形であるドキュメントをコレクションに保存します。次の例では、Restaurant
クラスの場合、対応するコレクションの名前は restaurants
です。 Person
クラスの場合、対応するコレクションの名前は people
です。
class Restaurant include Mongoid::Document end class Person include Mongoid::Document end
ただし、複数形のデフォルトルールは必ずしも機能するとは限りません。例、モデルの名前が Rey
であるとします。スペイン語でこの単語の複数形は reyes
ですが、デフォルトのコレクション名は reys
です。
ActiveSupport::Inflector::Infinity.plural インスタンスメソッドを呼び出し、クラスの単数形と複数形を渡すことで、モデルクラスに新しい複数形のルールを作成できます。次の例ではreyes
の複数形としてrey
を指定しています。
ActiveSupport::Inflector.inflections do |inflect| inflect.plural("rey", "reyes") end
その結果、Mongoid は Rey
モデルクラスのドキュメントを reyes
コレクションに保存します。
注意
BSONドキュメント構造
Mongoid はドキュメントをデータベースに保存するときに、 Rubyオブジェクトを次の構造を持つBSONドキュメントに直列化します。
{ "_id" : ObjectId("4d3ed089fb60ab534684b7e9"), "title" : "Sir", "name" : { "_id" : ObjectId("4d3ed089fb60ab534684b7ff"), "first_name" : "Durran" }, "addresses" : [ { "_id" : ObjectId("4d3ed089fb60ab534684b7e0"), "city" : "Berlin", "country" : "Deutschland" } ] }
永続性コンテキスト属性
すべてのモデルクラスには次のメソッドが含まれています。これを使用して、Mongoid がモデルを永続化する場所に関する情報を検索できます。
client_name
:クライアント名を検索しますdatabase_name
:データベース名を検索しますcollection_name
:コレクション名を検索します
次の例は、 Band
クラスのドキュメントが保存されているクライアント、データベース、コレクションの名前を検索して出力する方法を示しています。
puts Band.client_name puts Band.database_name puts Band.collection_name
default my_bands bands
永続性設定をカスタマイズする
Mongoid は、永続性構成をカスタマイズするためのモデルレベルとランタイムの両方のオプションを提供します。次のセクションで、これらのオプションについて説明します。
モデルレベルの永続性オプション
モデルクラス名の複数形とは異なる名前で、モデルのドキュメントをコレクションに保存するとします。 Mongoid がモデルのドキュメントを保存するコレクション、データベース、またはクライアントを変更するには、store_in
コマンドを使用します。次の例は、 store_in
マイクロを使用して、analytics
という名前のクライアント内の other
データベースに citizens
というコレクションに Person
クラスのドキュメントを保存する方法を示しています。
class Person include Mongoid::Document store_in collection: "citizens", database: "other", client: "analytics" end
store_in
マイクロは Lambda 関数を受け入れることもできます。これは、定数文字列を使用できない値を含む永続性コンテキストを定義する場合に役立ちます。
このパターンは、複数のユーザーがアプリケーションへの共通のアクセスを共有する マルチテナントアプリケーションで使用することができます。ラムダを使用すると、現在のスレッドに対してローカルの情報に基づいて永続性コンテキストを定義し、ユーザーがお互いのデータにアクセスできないようにすることができます。
次の例では、スレッド ローカル変数によって決定されたデータベースにドキュメントを保存します。
class Band include Mongoid::Document store_in database: ->{ Thread.current[:database] } end
ランタイム永続化オプション
モデルクラスまたはインスタンスの with
メソッドを使用して、実行時に操作のグループのモデルの永続構成を変更できます。
モデルクラスまたはインスタンスで with
メソッドを呼び出し、永続性コンテキストを定義するオプションを渡します。 with
メソッドは、次の 2 つの方法で呼び出すことができます。
with(context, options)
:context
はMongoid::PersistenceContext
のインスタンスであり、options
はカスタマイズ可能なオプションのセットを表すハッシュです。with(options)
:options
は、カスタマイズ可能なオプションのセットを表すハッシュです。
次に、 ブロックを使用して、指定されたコンテキストで実行する操作を定義します。定義するコンテキストは、ブロック内のコードの実行中にのみ存在します。
デフォルトでは 、Mongoid は bands
と呼ばれるコレクションに Band
クラスのドキュメントを保存します。次のコード例では、 with
メソッドを使用して、別のクライアント、データベース、コレクションを一時的に使用し、Band
クラスのドキュメントで操作を実行します。
class Band include Mongoid::Document field :name, type: String field :likes, type: Integer end # Creates document in 'bands' collection in 'music-non-stop' database within # default cluster Band.with(database: "music-non-stop") do |band_class| band_class.create(name: "Medusa and the Polyps") end # Deletes all documents in 'artists' collection within default database Band.with(collection: "artists") do |band_class| band_class.delete_all end band = Band.new(name: "Japanese Breakfast") # Perform operations on tertiary cluster band.with(client: :tertiary) do |band_object| band_object.save! band.save! end
注意
クライアントを定義する
前の例では、mongoid.yml
ファイルの clients
の下に tertiary
クラスターを定義する必要があります。
重要
ブロック スコープ
ブロックを使用して with
メソッドを呼び出す必要があります。これは、Mongoid が メソッドに渡したオプションを使用して、バックグラウンドで新しいクライアントを作成するためです。ブロックはこのクライアントのスコープを定義するため、閉じてリソースを解放できます。
読み取り操作または書込み操作で with
メソッド構成オプションを渡すこともできます。構成は、指定されたタイプの操作にのみ適用されます。
次の例では、 with
メソッドを使用して、ブロック内のすべての読み取り操作にセカンダリノードを使用することを指定します。
Band.with(read: {mode: :secondary}) do Band.count # This write operation runs in the # new persistence context, but is # not affected by the read preference. Band.create(name: "Metallica") end
注意
コンテキストでの整合性の確保
あるコンテキストで操作を実行すると、Mongoid は異なるコンテキストで自動的に同じ操作を実行しません。例、Band
モデルドキュメントをartists
コレクションに挿入しても、同じドキュメントはbands
コレクションに挿入されません。
グローバル永続化コンテキスト
このセクションの前の例では、永続化コンテキストは ブロックのスコープ内でのみ変更されました。 Mongoid を使用して、プログラム内のすべての操作が使用するカスタム永続性コンテキストをグローバルに定義できます。これにより、with
メソッドを繰り返し呼び出すことなく、実行時にすべての操作の永続性コンテキストを変更できます。
次のメソッドを使用して、プログラム内で永続性コンテキストをグローバルに定義できます。
Mongoid.override_client
: Mongoid は、指定されたクライアント上ですべての操作を実行します。Mongoid.override_database
: Mongoid は、指定されたデータベースに対してすべての操作を実行します。
次のコード例では、アプリケーションはさまざまなデータベースにさまざまなロケールの情報を保存しています。このコードは、Mongoid.override_database
メソッドを使用して、ロケールに基づいて永続性コンテキストをグローバルに設定する方法を示しています。
class BandsController < ApplicationController before_action :switch_database after_action :reset_database private def switch_database I18n.locale = params[:locale] || I18n.default_locale Mongoid.override_database("my_db_name_#{I18n.locale}") end def reset_database Mongoid.override_database(nil) end end
前の例では、Mongoid は、ロケールによって決定された代替データベース上のこのスレッドで他のすべての操作を実行しています。 after_action
マイクロはオーバーライド オプションを nil
に設定しているため、永続性設定が変更されていない後続のリクエストはデフォルト構成を使用します。
クライアントとコレクションのアクセス
モデル インスタンスまたはドキュメントインスタンスのクライアントまたはコレクションには、mongo_client
と collection
クラスメソッドを使用します。
Band.mongo_client band.mongo_client Band.collection band.collection
これらのメソッドを使用する場合、「 ランタイム永続性オプション 」セクションの例と同様に、with
メソッドを呼び出してランタイム永続性オプションを設定することもできます。
mongo_client.with
次のコード例では、 Band
モデルクラスで使用されるクライアントにアクセスします。次に、クライアントの with
メソッドを使用して music
データベースに書き込み、w
書込みオプションを 0
に設定して書込み確認を要求しないようにします。
Band.mongo_client.with(write: { w: 0 }, database: "music") do |client| client[:artists].find(...) end
collection.with
コレクションの :read
オプションと :write
オプションを上書きするには、 with
メソッドを使用します。次の例は、 with
メソッドを使用して w
書込みオプションを 0
に設定する方法を示しています。
Band.collection.with(write: { w: 0 }) do |collection| collection[:artists].find(...) end
API ドキュメント
このガイドで言及されているメソッドの詳細については、次のAPIドキュメントを参照してください。