0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Rails初学者】Railsで複数カラムのユニーク制約を追加する

Posted at

こんにちは。
rails初学者です。
自分用備忘録のために、記事をまとめます。
「特定の2つ以上のカラムの組み合わせを、重複登録できないようにする」というテーマです。


やりたいこと

特定の2つ以上のカラムの組み合わせを、重複登録できないようにする。

例:
同じユーザーが同じ商品に複数レビューしない
同じ生徒が同じ授業に二重登録しない


モデル側でバリデーションを追加

Railsのモデルで「この組み合わせは重複させないよ」とルールを決める。

class Enrollment < ApplicationRecord
  belongs_to :student
  belongs_to :course
  
  # 同じ生徒が同じ授業に重複登録できないようにする
  validates :student_id, uniqueness: {
    scope: :course_id,
    message: "はこの授業にすでに登録されています"
  }
end

データベースにユニーク制約を追加

① マイグレーション作成
アプリ側のバリデーションだけだと、同時に複数の人が操作したときなどにミスが起こる可能性があるため、DBでも絶対に重複が入らないようにガードしておく。

bin/rails generate migration add_unique_index_to_enrollments

②マイグレーションファイルを編集

 class AddUniqueIndexToEnrollments < ActiveRecord::Migration[8.0]
  def change
    add_index :enrollments, [:student_id, :course_id], unique: true
  end
end

③実行

bin/rails db:migrate

すでに重複データがないか確認する

重複していたら、マイグレーションでエラーになる。
Railsコンソールで確認する。

bin/rails console
Enrollment
  .group(:student_id, :course_id)
  .having("COUNT(*) > 1")
  .count

結果が {} ならOK

まとめ

対策場所 目的
モデル エラーメッセージで教えてあげる
DB 絶対に重複を防ぐ最後の砦

バリデーションとユニーク制約の違い

比較 モデルのバリデーション DBのユニーク制約
目的 ユーザーに優しく教える データの正しさを守る
実行のタイミング アプリが保存しようとしたとき データベースに保存するとき

初学者のため、間違えていたらすいません。

0
0
0

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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?