誤りがあれば教えていただけると幸いです。
アソシエーションって何?
日本語訳すると、「つながり」とか「関係性」とか訳される。MVCフレームワークを使うと出てくるアソシエーションは、モデル同士の関係性のこと。
すごく大雑把に言えば、テーブルの JOIN の繋ぎ方のこと。たぶん合ってる。
なぜアソシエーションが必要なのか?
設定しておくと Rails では JOIN を明示的に書かなくても SELECT できたり、紐付いたデータを一緒に削除できたり、色々とフレームワークの支援を得られる。
何故アソシエーションなの?(Why Associations?) - Active Record Associations - 株式会社ウサギィwiki
Active Record Associations — Ruby on Rails Guides
MVC モデルにおける Model の関係性
- 1対1関連(has_one, belongs_to)
- 経由モデルありの1対1関連(has_one :through)
- 1対多関連(has_many, belongs_to)
- 中間テーブルに属性ありの多対多関連(has_many :through)
- 中間テーブルに属性なしの多対多関連(has_and_belongs_to_many)
- ポリモーフィック関連(has_many :as)
ちゃんと理解するために身近なサンプルを作ってみることにした。
1対1関連(has_one, belongs_to)
User - Blog上記のような 1 User に 1 Blog というブログサービスを想定したアソシエーションの設定は以下のようになる。
class User < ActiveRecord::Base has_one :blog end
class Blog < ActiveRecord::Base belongs_to :user endhas_one アソシエーション - Active Record Associations - 株式会社ウサギィwiki
belongs_to アソシエーション - Active Record Associations - 株式会社ウサギィwiki
The belongs_to Association - Active Record Associations — Ruby on Rails Guides
The has_one Association - Active Record Associations — Ruby on Rails Guides
経由モデルありの1対1関連(has_one :through)
User - Blog - SettingUser から Blog を通して Setting にアクセスするような3つのモデルの直線的な関係性は以下のように設定する。
class User < ActiveRecord::Base has_one :blog has_one :setting, through: :blog end
class Blog < ActiveRecord::Base belongs_to :user has_one :setting end
class Setting < ActiveRecord::Base belongs_to :blog endhas_one :through アソシエーション - Active Record Associations - 株式会社ウサギィwiki
The has_one :through Association - Active Record Associations — Ruby on Rails Guides
1対多関連(has_many, belongs_to)
Category - Article1 カテゴリに複数の記事、1 記事に 1 カテゴリという関係性を定義したい場合は以下のように設定する。
class Category < ActiveRecord::Base has_many :article end
class Article < ActiveRecord::Base belongs_to :category endhas_many アソシエーション - Active Record Associations - 株式会社ウサギィwiki
The has_many Association - Active Record Associations — Ruby on Rails Guides
中間テーブルに属性ありの多対多関連(has_many :through)
Blog - Reader - User中間テーブルが属性(理論的な意味でのカラムのこと)を持つ際の多対多の関連性は以下のように定義する。
class Blog < ActiveRecord::Base has_many :readers has_many :users, through: :readers end
class Reader < ActiveRecord::Base belongs_to :user belongs_to :blog end
class User < ActiveRecord::Base has_many :readers has_many :blogs, through: :readers endhas_many :through アソシエーション - Active Record Associations - 株式会社ウサギィwiki
The has_many :through Association - Active Record Associations — Ruby on Rails Guides
中間テーブルに属性なしの多対多関連(has_and_belongs_to_many)(HABTM)
Article - Tag中間テーブルが属性を持たず、2つのテーブルの関係性の情報しか持たない場合は以下のように定義する。
class Article < ActiveRecord::Base has_and_belongs_to_many :tags end
class Tag < ActiveRecord::Base has_and_belongs_to_many :articles end
has_and_belongs_to_many アソシエーションの規約
- 中間テーブルを作成しなければならない。
- 中間テーブルのテーブル名は参照先のテーブル名を辞書順に「_」で連結しなければならない。(※)
- 中間テーブルの主キー列を無効化しなくてはならない。
- 中間テーブルの外部キー列は「参照先のモデル名_id」の形式にしなければならない。
- 中間テーブルのタイムスタンプ列を削除しなくてはならない。
join_table でテーブル名を指定すれば任意のテーブル名を指定することができる。
rails g migration CreateArticlesTags でマイグレーションファイルが生成されるので
上記の規約に従い、以下のように修正する。
class CreateArticlesTags < ActiveRecord::Migration def change create_table :articles_tags, :id => false do |t| t.references :article, index: true t.integer :article_id t.references :tag, index: true t.integer :tag_id end end endhas_and_belongs_to_many アソシエーション - Active Record Associations - 株式会社ウサギィwiki
The has_and_belongs_to_many Association - Active Record Associations — Ruby on Rails Guides
[Rails]中間テーブルを使って他テーブルの情報を参照する - has_and_belongs_to_many (m:n) のケース
has_and_belongs_to_many アソシエーションのための結合テーブルの作成 - 株式会社ウサギィwiki
Creating Join Tables for has_and_belongs_to_many Associations — Ruby on Rails Guides
ポリモーフィック関連(has_many :as)
Blog - Article └ Picture ┘あるモデルが1つ以上の他のモデルに属する場合、以下のように定義する。
class Blog < ActiveRecord::Base has_many :pictures, as: :imageable end
class Article < ActiveRecord::Base has_many :pictures, as: :imageable end
class Picture < ActiveRecord::Base belongs_to :imageable, polymorphic: true endpolymorphic アソシエーション - Active Record Associations - 株式会社ウサギィwiki
Polymorphic Associations - Active Record Associations — Ruby on Rails Guides
参考
ruby/rails/RailsGuidesをゆっくり和訳してみたよ/Active Record Associations - 株式会社ウサギィwikiActive Record Associations — Ruby on Rails Guides