Edited at

Rails4のhas_many throughで多対多のリレーションを実装する

More than 3 years have passed since last update.

僕の運営しているサービス「Combinator」には、仲間集めをしているプロジェクトがたくさん掲載されています。それらのプロジェクトに対して、カテゴリを持たせるたせる開発を行います。具体的には、「Qiita」は、「ウェブサービス」といったカテゴリを持ったプロジェクトであるといった表現ができるようにします。

今回は、has_many throughで多対多のリレーションを実装しました。


1プロジェクトは複数のカテゴリに属するので、「プロジェクト」から見ると「カテゴリ」は"多"です。

1つのカテゴリには、多数のプロジェクトが存在するので、「カテゴリ」から見ると「プロジェクト」も"多"です。

このような関係を「多対多関係」といいます。



マイグレーションファイルを作成する

テーブルを普通に作成し、最後に中間テーブルに両方のテーブルの外部キーを定義して作成します。

Categoryモデルとcategoriesテーブルの作成します。


$ rails g model Category title:string

$ rake db:migrate


Projectモデルとprojectsテーブルの作成します。


$ rails g model Project title:string

$ rake db:migrate


CategoryProjectモデルとcategories_projectsテーブルの作成します。


$ rails g model CategoryProject category_id:integer project_id:integer

$ rake db:migrate



モデルにhas_manyを追加する


Categoryモデル


app/models/category.rb

class Category < ActiveRecord::Base

has_many :category_projects
has_many :projects, through: :category_projects
end

# throughオプションによりcategory_projects経由でprojectsにアクセスできるようになる
# category.projectsでプロジェクトにアクセスができる



Category_projectモデル(中間テーブル)


app/models/category_project.rb

class CategoryProject < ActiveRecord::Base

belongs_to :category
belongs_to :project
end


Projectモデル


app/models/project.rb

class Project < ActiveRecord::Base

has_many :category_projects
has_many :categories, through: :category_projects
end

# throughオプションによりcategory_projects経由でcategoriesにアクセスできるようになる
# project.categoriesでカテゴリにアクセスができる


これらによって、

あるCategory属性を持つProjectを全て抽出したり

あるProjectに付与されているCategory属性を抽出できるようになる。

Controller・View周りの実装については次回!

参照:

http://ruby-rails.hatenadiary.com/entry/20141204/1417688260