Railsのエラー『ActiveRecord::RecordNotUnique: Duplicate entry』の解決方法

このエラーは、データベースの一意制約(UNIQUE制約)に違反するデータを挿入または更新しようとした場合に発生する。主に、モデルのバリデーション不足や、トランザクションの競合が原因であることが多い。この記事では、エラーの原因と解決方法について詳しく説明する。
目次
エラーメッセージの例
ActiveRecord::RecordNotUnique: Duplicate entry 'example@example.com' for key 'users.email'
エラーの発生条件
- 一意制約を持つカラムに重複した値を挿入しようとした
- データベースのユニークインデックスに違反するデータを保存しようとした
- 並列処理による競合が発生した
- バリデーションの不足により、同じ値が登録されてしまった
データベースレベルでの一意制約の確認
データベースに設定されている一意制約を確認するには、以下のSQLを実行する。
SHOW CREATE TABLE users;
ActiveRecordのバリデーションを確認
モデルでvalidates :email, uniqueness: true
のようなバリデーションが設定されているかを確認する。
class User < ApplicationRecord
validates :email, uniqueness: true
end
バリデーションの追加
バリデーションが不足している場合は、uniqueness: true
を追加する。
class User < ApplicationRecord
validates :email, uniqueness: { case_sensitive: false }
end
データベースのユニークインデックスを確認
一意制約が適用されていない場合は、マイグレーションを作成する。
class AddUniqueIndexToUsers < ActiveRecord::Migration[6.0]
def change
add_index :users, :email, unique: true
end
end
トランザクションによる競合の対策
並列処理による競合が発生する場合、rescue
を使用してエラーを回避できる。
begin
user = User.create!(email: "example@example.com")
rescue ActiveRecord::RecordNotUnique
puts "Duplicate entry detected. Skipping creation."
end
アップサート(upsert)の活用
データを挿入する際に、重複がある場合は更新する方法。
User.upsert({ email: "example@example.com" }, unique_by: :email)
エラーが発生したデータの調査
データベース内で重複しているデータを確認する。
User.upsert({ email: "example@example.com" }, unique_by: :email)
まとめ
- ActiveRecordの
validates :uniqueness
を確認 - データベースの一意制約を確認
- ユニークインデックスを適切に設定
- トランザクションの競合を防ぐ
- アップサートを活用する
-
前の記事
MySQLのエラー『Lock Wait Timeout Exceeded』の解決方法 2025.06.06
-
次の記事
PHPのエラー『Notice: Non-static Method Should Not be Called Statically』の解決方法 2025.06.07
コメントを書く