1. ホーム
  2. ruby-on-rails

[解決済み] Railsで "has_many :through "リレーションはいつ使うのか?

2022-06-05 11:58:03

質問

私は has_many :through が何であるか、そしていつそれを使うべきか(そしてどのように)理解しようとしています。しかし、私はそれを得ることはできません。Beginning Rails 3を読んでいますし、ググってみましたが、理解することができません。

どうすれば解決するのでしょうか?

2つのモデルがあるとします。 UserGroup .

もし、ユーザーをグループに所属させたいのであれば、次のような方法があります。

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 :group_memberships
  has_many :groups, :through => :group_memberships  # Edit :needs to be plural same as the has_many relationship   
end

これで、通常の has_many のように扱えますが、必要なときにアソシエーションモデルの恩恵を受けることができます。

なお、これは has_one .

編集:ユーザーをグループに追加するのを簡単にする

def add_group(group, role = "member")
  self.group_associations.build(:group => group, :role => role)
end