Docs Menu

関連付け

Mongoid の関連付けにより、モデル間の関係を作成できます。 このガイドでは、Mongoid がサポートするさまざまなタイプの関連付けと、アプリケーションでそれらを使用する方法について学習できます。

参照された関連付けを使用すると、2 つのモデル間の関係を作成し、一方のモデルが他方のモデルを参照できます。 Mongoid は、次の参照される関連付けのタイプをサポートしています。

  • has_one

  • has_many

  • belongs_to

  • has_and_belongs_to_many

次のセクションでは、これらのそれぞれの関連付けタイプの使用方法について説明します。

has_one マイクロを使用して、1 つのクラスで表されるドキュメントに、別の 子クラスによって表されるドキュメントも含まれていることを宣言できます。 次の例では、 Studioクラスに対する has_one の関係を持つ Bandクラスを作成します。

class Band
include Mongoid::Document
has_one :studio
end

has_one 関連付けを宣言する場合、子クラスは親クラスを参照する belongs_to 関連付けも使用する必要があります。 次の例では、先行する Bandクラスで参照されている Studioクラスを示しています。

class Studio
include Mongoid::Document
belongs_to :band
end

belongs_toマイクロの詳細については、「 が に属する 」セクションを参照してください。

次の例に示すように、検証を使用して、子クラスが親クラスに存在することを確認できます。

class Band
include Mongoid::Document
has_one :studio
validates_presence_of :studio
end

Mongoid の検証の詳細については、「 検証ガイド 」を参照してください。

has_many マイクロを使用して、クラスによって表されるドキュメントに、別のクラスによって表される複数の子ドキュメントが含まれていることを宣言できます。 次の例では、 Membersクラスに対する has_many の関係を持つ Bandクラスを作成します。

class Band
include Mongoid::Document
has_many :members
end

has_many 関連付けを宣言する場合、子クラスは親クラスを参照する belongs_to 関連付けも使用する必要があります。 次の例では、先行する Bandクラスで参照されている Memberクラスを示しています。

class Member
include Mongoid::Document
belongs_to :band
end

マイクロの詳細については、 [ Belongs To ]belongs_to セクションを参照してください。

次の例に示すように、検証を使用して、子クラスが親クラスに存在することを確認できます。

class Band
include Mongoid::Document
has_many :members
validates_presence_of :members
end

Mongoid の検証の詳細については、「 検証ガイド 」を参照してください。

has_many 関連付けで any? メソッドを使用すると、データベースからドキュメントセット全体を取得せずに、関連付けにドキュメントが含まれているかどうかを判断できます。

次の例では、 any? メソッドを使用して、Bandクラスのドキュメントに Members ドキュメントが含まれているかどうかを判断します。

band = Band.first
band.members.any?

次の例に示すように、any? メソッドをフィルターと併用して、指定された条件に一致するドキュメントを検索することもできます。

band = Band.first
band.members.any? { |member| member.instrument == 'piano' }

any? メソッドにクラス名を指定すると、クラスの名前で結果をフィルタリングできます。 これは多態的な 関連付けに便利です。

class Drummer < Member
end
band = Band.first
band.members.any?(Drummer)

注意

関連付けられているクラスのデータが Mongoid に読み込まれた後は、any? メソッドに対する後続の呼び出しでは、データベースはクエリされません。 代わりに、Mongoid はメモリにすでにロードされているデータを使用します。

また、exists? メソッドを呼び出して、関連付け内に永続化されたドキュメントがあるかどうかを確認することもできます。 exists? メソッドは常にデータベースをクエリし、データベースに保存されているドキュメントのみをチェックします。 exists? メソッドはフィルタリングを許可しておらず、引数を受け入れません。

次の例では、 exists? メソッドを使用して、Bandクラスに永続化された Members ドキュメントがあるかどうかを判断します。

band = Band.create!
# Member is not persisted.
band.members.build
band.members.exists?
# Outputs: false
# Persist the member
band.members.map(&:save!)
band.members.exists?
# Outputs: true

belongs_to マイクロを使用して、1 つのクラスによって表されるドキュメントが、別のクラスによって表されるドキュメントの子であることを宣言します。 デフォルトでは 、親クラスの _idフィールドは子クラスに保存されます。 次の例では、 Bandクラスへの belongs_to の関連付けを持つ Membersクラスを作成します。

class Members
include Mongoid::Document
belongs_to :band
end

次の例に示すように、optional オプションを true に設定することで、Mongoid が関連付けられている親クラスの _id を保存せずにドキュメントをデータベースに永続化できるようにします。

class Members
include Mongoid::Document
belongs_to :band, optional: true
end

Tip

アプリケーションの 構成設定 で belongs_to_required_by_default 構成オプションを false に設定することで、belongs_to 関連付けのデフォルトの動作をグローバルに変更して、親クラスを不要にすることができます。

親クラスで一致する has_one または has_many の関連付けを指定しなくても、子クラスで belongs_to の関連付けを指定できます。 そうすると、親クラスから子ドキュメントのフィールドにはアクセスできませんが、親の _idフィールドなど、子クラスに保存されている親フィールドにはアクセスできます。 次の例では、BandクラスはMembersクラスにアクセスできませんが、MembersクラスはBandクラス にアクセスできます。

class Band
include Mongoid::Document
end
class Members
include Mongoid::Document
belongs_to :band
end

明確にするために、次の例に示すように、親クラスに子クラスへの has_one または has_many の関連付けが含まれていないことを示す、inverse_of オプションを nil に設定できます。

class Band
include Mongoid::Document
end
class Members
include Mongoid::Document
belongs_to :band, inverse_of: nil
end

has_and_belongs_to_many マイクロを使用して、クラスモデルに別のクラスとの多対多の関係が含まれていることを宣言します。 多対多の関係では、1 つのクラス内の各ドキュメントを別のクラスの複数のドキュメントに関連付けることができます 。 次の例では、 Membersクラスへの has_and_belongs_to_many の関係を持つ Bandクラスを作成します。 Bandドキュメントは複数の Members ドキュメントを参照でき、Membersドキュメントは複数の Band ドキュメントを参照できます。

class Band
include Mongoid::Document
has_and_belongs_to_many :members
end
class Members
include Mongoid::Document
has_and_belongs_to_many :bands
end

has_and_belongs_to_many の関連付けを宣言すると、両方のモデル インスタンスに関連付けられているドキュメントの _id 値のリストが保存されます。 関連するドキュメントの _id 値をモデル インスタンスの 1 つだけに保存するには、inverse_of オプションを nil に設定します。 次の例では、関連付けられているドキュメントの _id 値を Bandクラスのみに保存するように Mongoid に指示します。

class Band
include Mongoid::Document
has_and_belongs_to_many :tags, inverse_of: nil
end
class Tag
include Mongoid::Document
end

Tip

has_and_belongs_to_many の関連付けがあるドキュメントを更新すると、Mongoid は更新されたドキュメントの updated_atフィールドを設定しますが、関連付けられているドキュメントの updated_atフィールドは設定しません。

集計パイプラインを使用して、参照されている関連付け全体のドキュメントをクエリできます。 集計パイプラインと、複数のコレクションにわたるクエリを作成したり、指定した形式でデータを操作したりできます。 集計パイプライン の使用方法の詳細については、 集計ガイドを参照してください。

単純なクエリの場合は、関連付けを直接クエリできます。 コレクションを直接クエリする場合、コレクション自体にあるフィールドと値のみをクエリできます。 クエリ対象に関連付けられているコレクションを直接クエリすることはできません。

例、次の Band クラスと Tour クラスについて考えてみます。

class Band
include Mongoid::Document
has_many :tours
field :name, type: String
end
class Tour
include Mongoid::Document
belongs_to :band
field :year, type: Integer
end

次の例では、 year の値が 2000 以上であるドキュメントを Tourクラスでクエリし、それらのドキュメントの band_id を保存します。 次に、それらの band_id 値を持つドキュメントを Bandクラスでクエリします。

band_ids = Tour.where(year: {'$gte' => 2000}).pluck(:band_id)
bands = Band.find(band_ids)

埋め込み関連付けを使用して、異なるタイプのドキュメントを同じコレクションに保存できます。 Mongoid は次のマイクロとの埋め込み関連付けをサポートしています。

  • embeds_one

  • embeds_many

  • embedded_in

  • recursively_embeds_one

  • recursively_embeds_many

次のセクションでは、これらの関連付けタイプの使用方法について説明します。

クラスモデルに別のクラスタイプの埋め込みドキュメントが含まれていることを指定するには、親クラスの embeds_one マイクロと 埋め込みクラスの embedded_in マイクロを使用します。 次の例では、埋め込まれた Labelクラスを持つ Bandクラスを作成しています。

class Band
include Mongoid::Document
embeds_one :label
end
class Label
include Mongoid::Document
field :name, type: String
embedded_in :band
end

Mongoid は、親ドキュメントの embeds_one マイクロで埋め込まれたドキュメントを、埋め込みクラスと同じ名前のフィールドとして保存します。 前述の Label ドキュメントは、次の例に示すように、 Bandドキュメントに保存されています。

# Band document
{
"_id" : ObjectId("..."),
"label" : {
"_id" : ObjectId("..."),
"name" : "Periphery",
}
}

次の例に示すように、store_as オプションを使用して、埋め込みドキュメントを別の名前で保存することができます。

class Band
include Mongoid::Document
embeds_one :label, store_as: "record_label"
end

クラスモデルに異なるクラスタイプの複数の埋め込みドキュメントが含まれていることを指定するには、親クラスの embeds_many 構造と 埋め込みクラスの embedded_in マイクロを使用します。 次の例では、複数の埋め込まれた Album 型ドキュメントを含む Bandクラスを作成しています。

class Band
include Mongoid::Document
embeds_many :albums
end
class Album
include Mongoid::Document
field :name, type: String
embedded_in :band
end

Mongoid は、親ドキュメントに embeds_many マイクロで埋め込まれたドキュメントを、埋め込みクラスと同じ名前の配列フィールドとして保存します。 前述の Album ドキュメントは、次の例に示すように、 Bandドキュメントに保存されています。

{
"_id" : ObjectId("..."),
"albums" : [
{
"_id" : ObjectId("..."),
"name" : "Omega",
}
]
}

次の例に示すように、store_as オプションを使用して、埋め込みドキュメントを別の名前で保存することができます。

class Band
include Mongoid::Document
embeds_many :albums, store_as: "records"
end

recursively_embeds_onerecursively_embeds_many マイクロを使用して、同じタイプの 1 つ以上のドキュメントを親クラスに埋め込むことができます。 どちらのドキュメントも、parent_* メソッドと child_* メソッドを介して親ドキュメントと子ドキュメントにアクセスできます。ここで、* はクラスの名前を表します 。 次の例では、複数のバンド名を表すために他の複数の Band ドキュメントを再帰的に埋め込む Bandクラスを作成します。

class Band
include Mongoid::Document
field :name, type: String
recursively_embeds_many
end

次の例に示すように、parent_band メソッドと child_band メソッドを介して親ドキュメントと子ドキュメントにアクセスできます。

root = Band.new(name: "Linkin Park")
# Add child bands
child_one = root.child_band.build(name: "Lincoln Park")
child_two = root.child_band.build(name: "Xero")
# Access parent band
child_one.parent_band
# Outputs: root

ドット表記を使用して親クラスのコレクションをクエリするときに、埋め込みドキュメントにアクセスできます。

次の例では、ドット表記を使用して、Bandクラスに埋め込まれている Tour 型のドキュメントをクエリします。 クエリでは、tours.year の値が 2000 以上であるドキュメントが返されます。

Band.where('tours.year' => {'$gte' => 2000})

次の例に示すように、pluckプロジェクションメソッドを使用すると、関連付けられている親ドキュメントを取得せずに埋め込みドキュメントを取得できます。

# Get awards for bands that have toured since 2000
Band.where('tours.year' => {'$gte' => 2000}).pluck(:awards)

Mongoid クエリ メソッドを使用して 埋め込み一致 を実行できます。これにより、アプリケーションにすでにロードされているドキュメントの埋め込み関連付けに対してクエリを実行できます。Mongoid は、サーバーにクエリを送信せずに埋め込み一致を実装します。

次のクエリ演算子は埋め込み一致でサポートされています。

次の例では、 $gte 比較演算子を使用して、ロードされた Bandドキュメントの埋め込み toursフィールドをクエリします。

band = Band.where(name: 'Astral Projection').first
tours = band.tours.where(year: {'$gte' => 2000})

ロードされたドキュメントでの埋め込み一致には、次の既知の制限があります。

  • 次の機能では、埋め込み一致は実装されていません。

  • Mongoid は、$gte$lte 条件を使用して、Range 引数をハッシュに展開します。 これにより、場合によっては無効なクエリが発生し、InvalidQuery 例外が発生します。

  • $regex 演算子では、$optionsフィールドにオプションも提供しながら、正規式オブジェクトをパターンとして指定することはできません。 正規式パターンが string の場合にのみオプションを指定できます。

  • MongoDB Serverバージョン 4.0 以前では、$type 引数は厳密に検証されません。

デフォルトでは 、Mongoid は埋め込みドキュメントに _idフィールドを追加します。 このフィールドは、モデルで _idフィールドを明示的に指定し、デフォルト値を省略することで、埋め込みドキュメントから省略できます。 次の例ではMongoid に Albumsクラスに _idフィールドを追加しないように指示します。

class Album
include Mongoid::Document
field :name, type: String
field :_id, type: Object
embedded_in :band
end

前述の Albumsクラスでは、_idフィールドは自動的に追加されません。 デフォルト値がない場合、モデルでデフォルト値を指定しない限り、Mongoid はデータベースに値を保存しません。

次のいずれかの方法を使用して、embeds_many の関連付けから子ドキュメントを削除できます。

  • clear

  • delete_all

  • destroy_all

clearメソッドは $unset 演算子を使用して、親ドキュメントから埋め込み関連付け全体を削除します。clear メソッドは destroy コールバックを実行しません。 次の例では、 clear メソッドを使用して、Bandクラスからすべての埋め込み関連付けを削除します。

band = Band.find(...)
band.tours.clear

delete_allメソッドは $pullAll 演算子を使用して、埋め込み関連付け内のドキュメントを削除します。delete_all は、関連付けがまだ読み込まれていない場合はその関連付けを読み込み、アプリケーションに存在するドキュメントのみを削除します。 delete_all メソッドは destroy コールバックを実行しません。 次の例では、 delete_all メソッドを使用して、Bandクラスからすべての埋め込み Album ドキュメントを削除します。

band = Band.find(...)
band.tours.delete_all

destroy_allメソッドでは、埋め込み関連付け内のドキュメントを削除するために、 $pullAll 演算子も使用されます。また、関連するドキュメントに定義されている destroy コールバックも実行します。 次の例では、 destroy_all メソッドを使用して、Bandクラスからすべての埋め込み Album ドキュメントを削除します。

band = Band.find(...)
band.tours.destroy_all

Mongoid を使用して、アプリケーション内で関連付けがどのように動作するかをカスタマイズできます。 次のセクションでは、関連付けの動作をカスタマイズする方法について説明します。

拡張機能を使用すると、関連付けにカスタム機能を追加できます。 次の例に示すように、関連付け定義で ブロックを指定することで、関連付けで拡張機能を定義できます。

class Band
include Mongoid::Document
embeds_many :albums do
def find_by_name(name)
where(name: name).first
end
end
end
band.albums.find_by_name("Omega") # returns album "Omega"

関連付けのカスタムクラス名を指定するには、class_name コマンドを使用します。 これは、クラスの名前とは異なるものに関連付けに名前を付けたい場合に便利です。 次の例では、 class_name マイクロを使用して、records という埋め込み関連付けが Albumクラスを表すことを指定します。

class Band
include Mongoid::Document
embeds_many :records, class_name: "Album"
end

デフォルトでは 、Mongoid は関連付けを検索するときに親クラスの _idフィールドを使用します。 primary_keyforeign_key マイクロを使用して、使用する別のフィールドを指定できます。 次の例ではBandクラスの albums 関連付けの新しいプライマリキーと外部キーを指定します。

class Band
include Mongoid::Document
field :band_id, type: String
has_many :albums, primary_key: 'band_id', foreign_key: 'band_id_ref'
end
class Album
include Mongoid::Document
field :band_id_ref, type: String
belongs_to :band, primary_key: 'band_id', foreign_key: 'band_id_ref'
end

has_and_belongs_to_many の関連付けを指定している場合は、inverse_primary_keyinverse_foreign_key マイクロも使用できます。 inverse_primary_key マニュアルは、リモート モデルがドキュメントを検索するために使用するローカル モデルのフィールドを指定します。 inverse_foreign_key マイクロは、inverse_primary_key で見つかった値を保存するリモート モデルのフィールドを指定します。

次の例では、 has_and_belongs_to_many の関連付けにおいて Band クラスと Members クラスの新しいプライマリキーと外部キーを指定します。

class Band
include Mongoid::Document
field :band_id, type: String
field :member_ids, type: Array
has_many :members,
primary_key: 'member_id', foreign_key: 'member_ids',
inverse_primary_key: 'band_id', inverse_foreign_key: 'band_ids'
end
class Member
include Mongoid::Document
field :member_id, type: String
field :band_ids, type: Array
has_many :bands,
primary_key: 'band_id', foreign_key: 'band_ids',
inverse_primary_key: 'member_id', inverse_foreign_key: 'member_ids'
end

scope パラメータを使用して、関連付けの範囲を指定できます。 scope パラメーターは、Mongoid が関連付けの一部と見なすドキュメントを決定します。 スコープ指定された関連付けでは、クエリ時にスコープ条件に一致するドキュメントのみが返されます。 scope は、アーティッドがゼロの Proc または、関連付けられたモデル上の名前付きスコープを参照する Symbol に設定できます。 次の例では、 Bandクラスでの関連付けにカスタム スコープを設定します。

class Band
include Mongoid::Document
has_many :albums, scope: -> { where(published: true) }
# Uses a scope called "upcoming" on the Tour model
has_many :tours, scope: :upcoming
end

注意

スコープ条件に一致しないドキュメントを 関連付けに追加できます。 Mongoid はドキュメントをデータベースに保存し、関連するメモリに表示されます。 ただし、関連付けをクエリするときに、ドキュメントは表示されません。

Mongoid が関連付けをメモリに読み込むとき(デフォルトでは )、validates_associated マイクロを使用して子も存在することを検証します。 Mongoid は、次の関連付けタイプの子を検証します。

  • embeds_many

  • embeds_one

  • has_many

  • has_one

  • has_and_belongs_to_many

この検証動作をオフにするには、次の例に示すように、関連付けを定義するときに validate マイクロを false に設定します。

class Band
include Mongoid::Document
embeds_many :albums, validate: false
end

Mongoid は、子クラスの 1 対 1 および 1 対多の関連付けの多形データをサポートします。 多形関連付けにより、1 つの関連付けに異なるクラスタイプのオブジェクトを含めることができます。 子関連付けで polymorphic オプションを true に設定し、親関連付けに as オプションを追加することで、多態的な 関連付けを定義できます。 次の例では、 Bandクラスで多態的な 関連付けを作成しています。

class Tour
include Mongoid::Document
has_one :band, as: :featured
end
class Label
include Mongoid::Document
has_one :band, as: :featured
end
class Band
include Mongoid::Document
belongs_to :featured, polymorphic: true
end

前の例では、Bandクラスの :featured の関連付けに Label または Album のドキュメントのいずれかを含めることができます。

重要

Mongoid は、子から親への多形データのみをサポートします。 親の has_one または has_many の関連付けを多形として指定することはできません。

has_and_belongs_to_many 関連付けは多形データをサポートしていません。

バージョン 9.0.2 以降、 Mongoid は、グローバル レジストリを通じてカスタム多形型をサポートします。 別のキーを指定して異なるクラスを表すことができ、コードを データから切り離します。 次の例ではBandクラスの代替キーとして string "artist" を指定します。

class Band
include Mongoid::Document
identify_as 'artist'
has_many :albums, as: :record
end

前の例では、identify_as ディレクティブは Mongoid に指示して、データベースにBand クラスをstring"artist" として保存します。

次の例に示すように、複数のエイリアスを指定することもできます。

class Band
include Mongoid::Document
identify_as 'artist', 'group', 'troupe'
has_many :albums, as: :record
end

前の例では、artist はデフォルト名で、その他はレコードを検索する目的でのみ使用されています。 これにより、データの 関連付けを中断せずにコードをリファクタリングできます。

多形型エイリアスはグローバルです。 指定するキーは、コード ベース全体で一意である必要があります。 ただし、モデルのさまざまなサブセットに使用できる代替のリゾルバを登録することはできます。 この場合、キーは各リゾルバに対してのみ一意である必要があります。 次の例は、代替リゾルバを登録する方法を示しています。

Mongoid::ModelResolver.register_resolver Mongoid::ModelResolver.new, :mus
Mongoid::ModelResolver.register_resolver Mongoid::ModelResolver.new, :tool
module Music
class Band
include Mongoid::Document
identify_as 'bnd', resolver: :mus
end
end
module Tools
class Band
include Mongoid::Document
identify_as 'bnd', resolver: :tool
end
end

Music::BandTools::Band は両方とも "bnd" のエイリアスですが、各モデルは競合を回避するために独自のリゾルバを使用します。

参照された関連付けに dependent オプションを指定すると、ドキュメントが削除されたときに Mongoid が関連するドキュメントをどのように取り扱うかを指定できます。 次のオプションを指定できます。

  • delete_all: モデル コールバックを実行中せずにすべての子ドキュメントを削除します。

  • destroy: 子ドキュメントを削除し、すべてのモデル コールバックを実行します。

  • nullify: 子ドキュメントの外部キーを nil に設定します。 親ドキュメントのみが参照する場合、子ドキュメントが 孤立する 可能性があります。

  • restrict_with_exception: 子ドキュメントが空でない場合に例外が発生します。

  • restrict_with_error: 子ドキュメントが空でない場合は、操作をキャンセルし、false を返します。

dependent オプションを指定しない場合、親ドキュメントが削除されても Mongoid は子ドキュメントを変更せずに残ります。 子ドキュメントは削除された親ドキュメントを参照、親のみを介して参照されると、子ドキュメントは孤立します。

次の例ではBandクラスで dependent オプションを指定します。

class Band
include Mongoid::Document
has_many :albums, dependent: :delete_all
belongs_to :label, dependent: :nullify
end

デフォルトでは 、Mongoid は親ドキュメント を保存するときに、非埋め込み関連付けから関連するドキュメントを自動的に保存しません。 これにより、存在しないドキュメントへの参照が切断される可能性があります。

参照された関連付けで autosave オプションを使用すると、親ドキュメント を保存するときに関連するドキュメントを自動的に保存できます。 次の例では、関連付けられた Albumクラスを持つ Bandクラスを作成し、autosave オプションを指定しています。

class Band
include Mongoid::Document
has_many :albums
end
class Album
include Mongoid::Document
belongs_to :band, autosave: true
end
band = Band.new
album = Album.create!(band: band)
# The band is persisted at this point.

注意

Mongoid は、accepts_nested_attributes_for オプションを使用する関連付けにオート保存機能を自動的に追加します。

Mongoid は親ドキュメントに埋め込みドキュメントを保存するため、埋め込み関連付けに autosave オプションを指定する必要はありません。

has_oneembeds_one などの 1 対 1 の関連付けに autobuild オプションを追加すると、nil 関連付けにアクセスするときに新しいドキュメントを自動的にインスタンス化できます。 次の例では、 Bandクラスの関連付けに autobuild オプションを追加します。

class Band
include Mongoid::Document
embeds_one :label, autobuild: true
has_one :producer, autobuild: true
end

Mongoid がドキュメントに入力すると、ドキュメントのupdated_at フィールドが現在の日付と時刻に更新されます。任意の belongs_to 関連付けに touch オプションを追加すると、子ドキュメントが更新されるたびに Mongoid が親ドキュメントにアクセスするようになります。 次の例では、 Bandクラスの関連付けに touch オプションを追加します。

class Band
include Mongoid::Document
field :name
belongs_to :label, touch: true
end

touch オプションを使用して、親関連付けの別のフィールドをstring またはシンボルとして指定することもできます。 Mongoid が親関連付けにアクセスすると、updated_atフィールドと指定されたフィールドの両方が現在の日付と時刻に設定されます。

次の例ではMongoid に bands_updated_atフィールドにアクセスするように指示します。

class Band
include Mongoid::Document
belongs_to :label, touch: :bands_updated_at
end

注意

埋め込み関連付けでは、埋め込みドキュメントが操作されると、Mongoid はその親を再帰的に操作します。 このため、embedded_in の関連付けに touch 属性を追加することは不要です。

Mongoid は、embedded_in 関連付けでアクセスする追加フィールドの指定をサポートしていません。

関連付けられたフィールドに属するオブジェクトの数を保存するには、counter_cache オプションを使用します。 このオプションを指定すると、Mongoid はカウントを保存するために関連付けられたモデルに追加の属性を保存します。 このため、関連付けられているクラスで Mongoid::Attributes::Dynamic モジュールを指定する必要があります。

次の例ではBandクラスに counter_cache オプションを追加し、 Labelクラスで Mongoid::Attributes::Dynamic を指定します。

class Band
include Mongoid::Document
belongs_to :label, counter_cache: true
end
class Label
include Mongoid::Document
include Mongoid::Attributes::Dynamic
has_many :bands
end

関連付けを定義すると、Mongoid はその関連付けに関するメタデータを保存します。 メタデータにアクセスするには、モデルクラスまたはドキュメントで reflect_on_association メソッドを呼び出すか、特定のドキュメントのメタデータに直接アクセスします。 次の例は、 reflect_on_association メソッドと直接アクセスによってメタデータにアクセスする方法を示しています。

# Get the metadata for a named association from the class or document
Model.reflect_on_association(:<association_name>)
# Directly access metadata on a document
model.associations[:<association_name>]

注意

前の例の <association_name> を関連付け名に置き換えます。

すべての関連付けには、関連するドキュメントに関する情報を保存する属性が含まれています。 関連付けには、次の属性が含まれます。

  • _target: プロキシされたドキュメント(1 つまたは複数)

  • _base: 関連付けが定義されているドキュメント

  • _association: 関連付けに関する情報

次の例では、前述の各属性にアクセスします。

class Band
include Mongoid::Document
embeds_many :songs
end
Band.songs = [ song ]
Band.songs._target # returns [ song ]
Band.songs._base # returns band
Band.songs._association # returns the association metadata

次の表は、_association 属性に保存されている情報を示しています。

方式
説明

Association#as

多態的な子に対する親の名前。

Association#as?

as オプションが存在するかどうかを返します。

Association#autobuilding?

関連付けが自動構築であるかどうかを返します。

Association#autosaving?

関連付けが自動保存されているかどうかを返します。

Association#cascading_callbacks?

関連付けに親から階層化されたコールバックがあるかどうかを返します。

Association#class_name

プロキシされたドキュメントのクラス名。

Association#cyclic?

関連付けが定期的な関連付けであるかどうかを返します。

Association#dependent

関連付けの依存関係オプション。

Association#destructive?

関連付けに依存している削除または破棄するメソッドがある場合は true を返します。

Association#embedded?

関連付けが別のドキュメントに埋め込まれているかどうかを返します。

Association#forced_nil_inverse?

関連付けに nil の逆が定義されているかどうかを返します。

Association#foreign_key

外部キーフィールドの名前。

Association#foreign_key_check

外部キー フィールドのダーティ チェック メソッドの名前。

Association#foreign_key_setter

外部キー フィールドのセッターの名前。

Association#indexed?

外部キーが自動インデックス化されているかどうかを返します。

Association#inverses

すべての逆関連付けの名前。

Association#inverse

単一の逆関連付けの名前。

Association#inverse_class_name

逆側の関連付けのクラス名。

Association#inverse_foreign_key

逆側の外部キーフィールドの名前。

Association#inverse_klass

逆側の関連付けのクラス。

Association#inverse_association

逆側の関連付けのメタデータ。

Association#inverse_of

逆関連付けの明示的に定義された名前。

Association#inverse_setter

逆を設定するために使用されるメソッドの名前。

Association#inverse_type

逆の多形タイプフィールドの名前。

Association#inverse_type_setter

多形型フィールドの逆のセッターの名前。

Association#key

関連付けを取得するために使用される、属性のハッシュ内のフィールドの名前。

Association#klass

関連付け内のプロキシされたドキュメントのクラス。

Association#name

関連付け名。

Association#options

ActiveRecord とのAPI互換性のために self を返します。

Association#order

関連付けのカスタム並べ替えオプション。

Association#polymorphic?

関連付けが多形であるかどうかを返します。

Association#setter

関連付けを設定するフィールドの名前。

Association#store_as

埋め込み関連付けを保存する属性の名前。

Association#touchable?

関連付けにアクセス オプションがあるかどうかを返します。

Association#type

多形型を取得するフィールドの名前。

Association#type_setter

多形タイプを設定するフィールドの名前。

Association#validate?

関連付けに関連する検証があるかどうかを返します。