bootcamp
bootcamp copied to clipboard
ActiveRecord::RecordNotUniqueのエラーが出ないように修正
2つPRをcloseしている理由なのですが、push前にgit pull --rebase origin main
しておらず、自分のコミットでないものが入ってしまいました。1度目はそこから修正しようとしましたが余計に分からなくなった為closeしました。2度目は解決方法が分かったので、closeしました。
Issue
- #7888
概要
ActiveRecord::RecordNotUnique: PG::UniqueViolation: ERROR: duplicate key value violates unique constraint "index_reports_on_user_id_and_reported_on" DETAIL: Key (user_id, reported_on)=(2018, 2024-06-24) already exists.
とエラーが出るのを回避するための修正を行いました。
変更確認方法
-
ブランチ
bug/fix-unique-violation-cleanup
をローカルに取り込む -
rails console
でコンソールを立ち上げる -
以下のコマンドを実行してユーザーを定義
user = User.find_by(name: 'Hajime Tayo')
-
以下のコードを実行し、エラーが出ることを確認
report1 = Report.new( user: user, reported_on: '2001-08-08', title: 'test1', description: 'test', emotion: 'happy' ) begin report1.save!(validate: false) puts "レポート1: 保存" rescue => e puts "レポート1: エラー #{e.message}" end report2 = Report.new( user: user, reported_on: '2001-08-08', title: 'test2', description: 'test', emotion: 'happy' ) begin report2.save!(validate: false) puts "レポート2: 保存" rescue => e puts "レポート2: エラー #{e.message}" end
-
以下のコードを実行し、エラーが出ないでバリデーションが実行されていることを確認
report1 = Report.new( user: user, reported_on: '2000-08-07', title: 'test11', description: 'test', emotion: 'happy' ) if report1.save_with_uniqueness_check puts "レポート1: 保存" else puts "レポート1: エラー #{report1.errors.full_messages.join(', ')}" end report2 = Report.new( user: user, reported_on: '2000-08-07', title: 'test22', description: 'test', emotion: 'happy' ) if report2.save_with_uniqueness_check puts "レポート2: 保存" else puts "レポート2: エラー #{report2.errors.full_messages.join(', ')}" end
変更前
irb(main):134:1* report2 = Report.new(
irb(main):135:1* user: user,
irb(main):136:1* reported_on: '2014-08-04',
irb(main):137:1* title: 'test-2',
irb(main):138:1* description: 'test',
irb(main):139:1* emotion: 'happy'
irb(main):140:0> )
=>
#<Report:0x00007fad1cdbf698
...
irb(main):141:1* begin
irb(main):142:1* report2.save!(validate: false)
irb(main):143:1* puts "レポート2: 保存"
irb(main):144:1* rescue => e
irb(main):145:1* puts "レポート2: エラー #{e.message}"
irb(main):146:0> end
TRANSACTION (0.5ms) BEGIN
Report Create (7.8ms) INSERT INTO "reports" ("user_id", "title", "description", "created_at", "updated_at", "reported_on", "emotion") VALUES ($1, $2, $3, $4, $5, $6, $7) RETURNING "id" [["user_id", 253826460], ["title", "test-2"], ["description", "test"], ["created_at", "2024-08-13 02:36:58.965711"], ["updated_at", "2024-08-13 02:36:58.965711"], ["reported_on", "2014-08-04"], ["emotion", 2]]
TRANSACTION (0.5ms) ROLLBACK
レポート2: エラー PG::UniqueViolation: ERROR: duplicate key value violates unique constraint "index_reports_on_user_id_and_reported_on"
DETAIL: Key (user_id, reported_on)=(253826460, 2014-08-04) already exists.
=> nil
変更後
irb(main):038:1* report2 = Report.new(
irb(main):039:1* user: user,
irb(main):040:1* reported_on: '2024-08-02',
irb(main):041:1* title: '222',
irb(main):042:1* description: 'test',
irb(main):043:1* emotion: 'happy'
irb(main):044:0> )
=>
#<Report:0x00007fad1c60ba50
...
irb(main):045:1* if report2.save_with_uniqueness_check
irb(main):046:1* puts "レポート2: 保存"
irb(main):047:1* else
irb(main):048:1* puts "レポート2: エラー #{report2.errors.full_messages.join(', ')}"
irb(main):049:0> end
TRANSACTION (8.8ms) BEGIN
Report Exists? (21.0ms) SELECT 1 AS one FROM "reports" WHERE "reports"."user_id" = $1 AND "reports"."reported_on" = $2 LIMIT $3 [["user_id", 253826460], ["reported_on", "2024-08-02"], ["LIMIT", 1]]
TRANSACTION (0.7ms) ROLLBACK
レポート2: エラー 学習日はすでに存在します
=> nil