Docs Menu
Docs Home
/ / /
Mongoid
/

永続性設定

項目一覧

  • Overview
  • デフォルトのコレクション名
  • 永続性コンテキスト属性
  • 永続性設定をカスタマイズする
  • モデルレベルの永続性オプション
  • ランタイム永続化オプション
  • グローバル永続化コンテキスト
  • クライアントとコレクションのアクセス
  • mongo_client.with
  • collection.with
  • API ドキュメント

このガイドでは、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): contextMongoid::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_clientcollectionクラスメソッドを使用します。

Band.mongo_client
band.mongo_client
Band.collection
band.collection

これらのメソッドを使用する場合、「 ランタイム永続性オプション 」セクションの例と同様に、with メソッドを呼び出してランタイム永続性オプションを設定することもできます。

次のコード例では、 Band モデルクラスで使用されるクライアントにアクセスします。次に、クライアントの with メソッドを使用して musicデータベースに書き込み、w 書込みオプションを 0 に設定して書込み確認を要求しないようにします。

Band.mongo_client.with(write: { w: 0 }, database: "music") do |client|
client[:artists].find(...)
end

コレクションの :read オプションと :write オプションを上書きするには、 with メソッドを使用します。次の例は、 with メソッドを使用して w 書込みオプションを 0 に設定する方法を示しています。

Band.collection.with(write: { w: 0 }) do |collection|
collection[:artists].find(...)
end

このガイドで言及されているメソッドの詳細については、次のAPIドキュメントを参照してください。

戻る

アプリケーション構成