Railsマイグレーションで複数のカラムにユニーク制約を追加する方法
Railsマイグレーションで複数のカラムにユニーク制約を追加する方法
前提条件
- Ruby on Rails 6.1以上
- PostgreSQLデータベース
手順
- ターミナルで以下のコマンドを実行して、新しいマイグレーションファイルを作成します。
rails generate migration AddUniqueConstraintToUsers
- 作成されたマイグレーションファイル (
db/migrate/[timestamp]_add_unique_constraint_to_users.rb
) を開き、以下のコードを追加します。
class AddUniqueConstraintToUsers < ActiveRecord::Migration[6.1]
def change
# usersテーブルにnameとemailカラムの組み合わせにユニーク制約を追加
add_index :users, [:name, :email], unique: true
end
end
- マイグレーションを実行します。
rails db:migrate
解説
add_index
メソッドは、テーブルにインデックスを追加します。unique: true
オプションは、インデックスの値がユニークである必要があることを指定します。- 上記の例では、
users
テーブルにname
とemail
カラムの組み合わせにユニーク制約を追加しています。
- 複数のカラムの組み合わせにユニーク制約を追加するには、
add_index
メソッドにカラム名を配列で渡します。 - ユニーク制約の名前を指定したい場合は、
:name
オプションを使用します。 - ユニーク制約を削除するには、
remove_index
メソッドを使用します。
注意事項
- ユニーク制約を追加すると、既存のデータに重複がある場合はエラーが発生します。
- ユニーク制約を追加する前に、データの整合性を確認することをおすすめします。
class User < ApplicationRecord
# nameとemailカラムの組み合わせはユニークである必要がある
validates_uniqueness_of [:name, :email]
end
このコードは、validates_uniqueness_of
メソッドを使用して、name
と email
カラムの組み合わせがユニークであることを検証しています。
validates_uniqueness_of
メソッドは、以下のオプションを受け取ります。
:message
- エラーメッセージ:scope
- ユニーク制約を適用する範囲:case_sensitive
- 大文字と小文字を区別するかどうか
詳細は、Railsガイドの バリデーション: https://railsguides.jp/active_record_validations.html を参照してください。
バリデーション
class User < ApplicationRecord
# nameとemailカラムの組み合わせはユニークである必要がある
validates_uniqueness_of [:name, :email]
end
この方法は、データベースにユニーク制約を追加するわけではないので、データベースレベルでの制約は必要ありません。
データベーストリガーを使用して、ユニーク制約を強制することができます。
CREATE TRIGGER unique_users_trigger
BEFORE INSERT ON users
FOR EACH ROW
BEGIN
IF EXISTS (
SELECT 1
FROM users
WHERE name = NEW.name
AND email = NEW.email
) THEN
RAISE EXCEPTION '重複したデータが存在します';
END IF;
END;
この方法は、データベースレベルでユニーク制約を強制することができますので、アプリケーションコードを変更することなく、重複データの挿入を防ぐことができます。
ユニークキー制約
ALTER TABLE users
ADD CONSTRAINT unique_users UNIQUE (name, email);
- シンプルな方法でユニーク制約を追加したい場合は、
validates_uniqueness_of
メソッドを使用するのがおすすめです。 - データベースレベルで厳格な制約を設けたい場合は、データベーストリガーまたはユニークキー制約を使用するのがおすすめです。
Railsアプリケーションで複数のカラムにユニーク制約を追加するには、いくつかの方法があります。
それぞれの方法にはメリットとデメリットがあるので、状況に合わせて最適な方法を選択してください。
ruby-on-rails database