回答:
2つのモデルがあるUser
としGroup
ます: と。
ユーザーをグループに所属させたい場合は、次のようにします。
class Group < ActiveRecord::Base
has_many :users
end
class User < ActiveRecord::Base
belongs_to :group
end
関連付けに関する追加のメタデータを追跡したい場合はどうなりますか?たとえば、ユーザーがグループに参加したとき、またはグループ内でのユーザーの役割は何か?
ここで、関連付けをファーストクラスオブジェクトにします。
class GroupMembership < ActiveRecord::Base
belongs_to :user
belongs_to :group
# has attributes for date_joined and role
end
これにより、新しいテーブルが導入さgroup_id
れ、ユーザーのテーブルから列が削除されます。
このコードの問題は、ユーザークラスを使用する他のすべての場所を更新して変更する必要があることです。
user.groups.first.name
# becomes
user.group_memberships.first.group.name
このタイプのコードは面倒で、このような変更を導入するのは面倒です。
has_many :through
両方の長所を提供します。
class User < ActiveRecord::Base
has_many :groups, :through => :group_memberships # Edit :needs to be plural same as the has_many relationship
has_many :group_memberships
end
これで通常のように扱うことができますがhas_many
、必要なときに関連モデルのメリットを享受できます。
でこれを行うこともできますhas_one
。
編集:ユーザーをグループに簡単に追加できるようにする
def add_group(group, role = "member")
self.group_associations.build(:group => group, :role => role)
end
user.groups << group
か?それとも、すべてこの協会によって処理されますか?
次のモデルがあるとします。
Car
Engine
Piston
車has_one :engine
エンジンエンジンbelongs_to :car
エンジンhas_many :pistons
ピストンbelongs_to :engine
車のhas_many :pistons, through: :engine
ピストンhas_one :car, through: :engine
基本的に、あなたは他のモデルへのモデルの関係を委任されているので、代わりにコールを有するのcar.engine.pistons
は、あなただけ行うことができますcar.pistons
has_many :through
また、has_and_belongs_to_many
リレーションシップは、他のテーブル間のリレーションシップを表す中間テーブルである結合テーブルを通じて機能します。JOINクエリとは異なり、データは実際にはテーブルに格納されます。
ではhas_and_belongs_to_many
、主キーは必要なく、ActiveRecordモデルではなくActiveRecordリレーションを介してレコードにアクセスします。通常、多対多の関係で2つのモデルをリンクする場合は、HABTMを使用します。
has_many :through
結合テーブルとRailsモデルとして対話する場合は、主キーと結合されたデータにカスタム列を追加する機能を備えた関係を使用します。後者は、結合された行に関連するデータでは特に重要ですが、実際には関連モデルには属していません。たとえば、結合された行のフィールドから派生した計算値を格納します。
ではActive Recordの組合に対するAガイド、勧告が読み取ります。
最も単純な経験則は、リレーションシップモデルを独立したエンティティとして使用する必要がある場合は、has_many:throughリレーションシップを設定する必要があるということです。リレーションシップモデルで何もする必要がない場合は、has_and_belongs_to_manyリレーションシップを設定する方が簡単な場合があります(ただし、データベースに結合テーブルを作成することを覚えておく必要があります)。
結合モデルで検証、コールバック、または追加の属性が必要な場合は、has_many:throughを使用する必要があります。
user
モデルにメソッドを追加してグループを追加する場所です。先ほど行った編集のようなもの。お役に立てれば。