LoginSignup
6

More than 3 years have passed since last update.

[Rails]多対多のリレーションで、カラムのペアにunique制約を付ける(最初から&後から)

Posted at

駆け出しエンジニアの簡単なメモです。
間違いや誤解を招くような書き方があればご指摘いただけると幸いです。

1.中間テーブル作成

ユーザー(User)が投稿(Post)をお気に入り登録できる機能を作成しよう→
postsテーブルとusersテーブルの間にbookmarksという中間テーブルを作成→

rails g model Bookmark user:references post:references

これによりusersテーブルとpostsテーブルの両方を参照するように指定できます。
user_idとpost_idのペアを作成する事で、「お気に入り登録している」という状態を作ります。
しかしながらこの場合、user_idとpost_idのペアが重複することは有り得ません。(既にお気に入り登録している投稿に更にお気に入り登録はできない)
データベースで矛盾が生じないように、二つのペアがuniqueであることを明示する必要が有ります。

2.1. unique制約を付ける(最初から)

作成されたマイグレーションファイルに追記します。

class CreateBookmarks < ActiveRecord::Migration[6.0]
  def change
    create_table :bookmarks do |t|
      t.references :user, null: false, foreign_key: true
      t.references :post, null: false, foreign_key: true

      t.timestamps

      #以下を追記
      t.index [:user_id, :post_id], unique: true
    end
  end
end


あとはrails db:migrateすればオーケーです。

2.2 unique制約を付ける(後から)

今回メモするきっかけになったことです。
「あっやべ!付け忘れた!」となって後から追加する方法を調べました。

migrationファイルを作成

rails g migration AddIndexUserIdAndPostIdToBookmarks

中身を記述

class AddIndexUserIdAndPostIdToBookmarks < ActiveRecord::Migration[6.0]
  def change
    add_index :bookmarks, [:user_id, :post_id], unique: true
  end
end

とてもシンプルで簡単でした。
あとはrails db:migrateでオーケー!

参考にさせていただいた記事
Ruby on RailsでDBにユニーク制約を付与する方法
Railsドキュメント

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6