データベース設計
投稿(postテーブル)に対してタグ(tagテーブル)付けができる機能を作るとします
一つの投稿は複数のタグを持つことができ、一つのタグは複数のタグを持つことができる場合、そのままアソシエーションを組んでしまうとデータベースの中身が複雑になってしまいます。
そのためどの投稿がどのタグに結びついているのかを記憶するテーブルを別に作り、整理します。
内容
postテーブルを作る
rails g model Post image:text
tagテーブルを作る
rails g model Tag name:string
中間テーブルを作る
中間テーブルは各モデルの複数形を名前をスネーク型で繋げます
今回の場合はPosts_tags
postとtagの結びつきを記憶するテーブルのため各idのカラムを作ります
refarencesの型はこの後記述するマイグレーションファイルに記載するforeighn_keyの制約に対応した型になります。
foreighn_keyはpost_idやtag_idカラムに対してpost_idに対応したpostsテーブルのidがあることを保証する制約です。
例)post_id:1 tag_id:1 であればpostsテーブルにid:1の投稿があり、tagsテーブルにもid:1があることを保証しています。
rails g model Posts_tags post_id:refaremces tag_id:refarences
アソシエーション
多対多テーブルのアソシエーションはthroughを使用します。
postとtagは関連しているがposts_tagsを経由して関連することを表します。
has_many :posts_tags
has_many :tags, through: :posts_tags
has_many :posts_tags
has_many :posts, through: :posts_tags
belongs_to :post
belongs_to :tag
マイグレーションファイル
class CreatePostsTags < ActiveRecord::Migration[5.2]
def change
create_table :posts_tags do |t|
t.refarence :post_id, foreign_key: true
t.refarences :tag_id, foreign_key: true
t.timestamps
end
end
end
完成
これで多対多テーブルの作成が完了します。
※sqliteでrefarences型を使用しようとしたところマイグレーションができませんでした。integer型に変更したところマイグレーションできたので、sqliteではrefarences型は使用できないようです。