永続性設定
ドキュメント ストレージ
Mongoid はデフォルトで、クラス名の複数形であるコレクションにドキュメントを保存します。 次の Person
クラスでは、ドキュメントが保存されるコレクションの名前はpeople
になります。
class Person include Mongoid::Document end
モデルクラス名の末尾には「s」を使用できません。これは、単語の複数形と見なされるためです。 たとえば、"Status" は "Statu" の複数形と見なされ、いくつかの既知の問題が発生します。
これは、Mongoid がファイル名とコレクション名からクラス名に変換するために使用するActiveSupport::Inflector#classify
の制限です。 モデル クラスにカスタムを指定することで、この問題を解決できます。 たとえば、次のコードはStatus
という名前のモデルを処理します。
ActiveSupport::Inflector.inflections do |inflect| inflect.singular("status", "status") end
モデルのドキュメントのコレクションは、ドキュメントを別の場所で保持したい場合は、クラス レベルで変更できます。 また、モデルがデフォルトから永続化されるデータベースとクライアントを変更することもできます。
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
ドキュメントが データベースに保存されると、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.client_name # => :default Band.database_name # => "mongoid" Band.collection_name # => :bands
カスタム
デフォルトとは異なるソース、またはデフォルトとは異なるオプションにドキュメントを永続化する場合がある場合があります。 Mongoid は、これのランタイム サポートとモデルごとのサポートを提供します。
モデルレベルの永続性オプション
モデルごとに、カスタム コレクション名、別のデータベース、または別のクライアントに保存するように指示できます。 次の例では、Band クラスは、クライアントが「analytics」を使用して、「Music」という名前のデータベース内の「artists」という名前のコレクションにデフォルトで保存されます。
client
オプションに指定される値は、mongoid.yml のclients
の下に構成する必要があることに注意してください。
class Band include Mongoid::Document store_in collection: "artists", database: "music", client: "analytics" end
store_in
マイクロが提供されていない場合、Mongoid はデフォルトのクライアントのデフォルトのデータベースにある「ands」という名前のコレクションにモデルを保存します。
ランタイム永続化オプション
モデル クラスまたは インスタンスでwith
メソッドを使用して、操作のグループの永続性に使用されるクライアント、データベース、コレクション、および MongoDB クライアント オプションのいずれかを変更できます。
Band.with(database: "music-non-stop") do |klass| klass.create(...) band = Band.first Band.create(...) end Band.with(collection: "artists") do |klass| klass.delete_all Band.delete_all end band.with(client: :tertiary) do |band_object| band_object.save! band.save! end
with
メソッドは、一時的な永続化コンテキストと、コンテキストでの操作に使用される MongoDB クライアントを作成します。 ブロック中、 with
が呼び出されたモデル クラスまたはインスタンスの永続化コンテキストは、一時的な永続化コンテキストに変更されます。 便宜上、 with
が呼び出されたモデル クラスまたはインスタンスは ブロックに降格します。
一時的な永続性コンテキストは、クエリと書込みの両方に適用されます。
異なる永続性コンテキストで永続性操作を実行する場合は注意が必要です。 たとえば、ドキュメントが一時的な永続性コンテキストに保存された場合、そのドキュメントはデフォルトの永続性コンテキストに存在せず、その後の更新は失敗します。
band = Band.new(name: "Scuba") band.with(collection: "artists") do |band_object| band_object.save! end # This will not save - updates the collection "bands" which does not have # the Scuba band band.update_attribute(likes: 1000) # This will update the document. band.with(collection: "artists") do |band_object| band_object.update_attribute(likes: 1000) end
Mongoid 6.0以降、 with
メソッドは常にブロックとともに呼び出される必要があり、一時的な永続化コンテキストはブロックの期間のみ存在します。 これは、 with
に渡されるオプションを使用して、 カバーの下に新しいクライアントが作成されるためです。 このクライアントを閉じ、関連するリソースを解放するには、このクライアントが使用できるスコープを明確に定義する必要があります。
グローバル オーバーライド
実行時にすべての操作の永続性コンテキストを切り替えたいが、コード全体で を使用したくない場合、Mongoid はこれをクライアントとデータベース レベルでグローバルに実行する機能を提供します。 このメソッドはMongoid.override_client
と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
上記の例では、すべての永続化操作が、このスレッド上の残りのすべての操作の代替データベースに保存されます。 これが、リクエスト後の でオーバーライドが nil に戻ります。これにより、ローカル パラメータのない後続のリクエストがデフォルト オプションを使用するようになります。
永続性コンテキストは、読み取り操作と書込み (write) 操作の両方に適用されます。 たとえば、セカンダリ読み取りは次のように実行できます。
Band.with(read: {mode: :secondary}) do Band.count end
クライアントとコレクションのアクセス
ドライバー レベルにドロップダウンして操作を実行する場合は、モデルまたはドキュメント インスタンスからmongoクライアントまたは コレクションを取得できます。
Band.mongo_client band.mongo_client Band.collection band.collection
ここから、クライアントの#with
を使用した同じランタイム永続性オプションも利用できます。
client = Band.mongo_client.with(write: { w: 0 }, database: "musik") client[:artists].find(...)
また、コレクション#with
を使用して、 コレクションの :read オプションまたは 書込みオプションを上書きすることもできます。
collection_w_0 = Band.collection.with(write: { w: 0 }) collection_w_0[:artists].find(...)