Help us understand the problem. What is going on with this article?

【Rails】一対一対多のアソシエーション

結局は基本的なことなのですが、少し変わると途端にハマってしまう。
アソシエーションがうまくいかずに時間を溶かしてしまったので、そんな過去の自分といるかもしれない未来の誰かのために書き残しておきます。

テーブル構造

UserモデルとTagモデルの中間テーブルから派生させたTagSettingモデルを作りました。
erd.jpg
ただ、今回の話にはUserモデルはあまり関係ありません。
また、この後「tag_usersとtag_settingsを別々にしなくていいんじゃないか?」という指摘を受けてテーブル構造を変えました。なので、例としては少々不適切かもしれませんがご容赦を。

モデルのアソシエーション

user.rb
class User < ApplicationRecord
  has_many :tag_users
  has_many :tags, through: :tag_users
  has_many :tag_settings
end
tag_user.rb
class TagUser < ApplicationRecord
  belongs_to :user
  belongs_to :tag
  belongs_to :tag_setting
end
tag_setting.rb
class TagSetting < ApplicationRecord
  has_one :tag_user
  has_one :tag, through: :tag_user
  belongs_to :user
end
tag.rb
class Tag < ApplicationRecord
  has_many :tag_users
  has_many :tag_settings, through: :tag_users
end

注意点

中間テーブルへのアソシエーションを追加する

has_many :tag_usersなしでhas_many :tag_settings, through: :tag_usersを定義することはできない。
また、中間テーブルへのアソシエーションの方を上に記述する必要がある。

単数形・複数形に注意する

has_many :tag_settings, through: :tag_users
has_manyのときは:throughも複数形

has_one :tag, through: :tag_user
has_oneのときは:throughも単数形

リンク

aiandrox
過去と未来の自分のために書く。タイポがお友達
https://blog.aiandrox.com
sight-visit
資格のオンライン予備校「資格スクエア」, 契約管理サービス「NINJA SIGN」を運営するスタートアップ
https://sight-visit.com
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away