bootcamp icon indicating copy to clipboard operation
bootcamp copied to clipboard

ActiveRecord::RecordNotUniqueのエラーが出ないように修正

Open su-su-su-su opened this issue 6 months ago • 14 comments

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.

とエラーが出るのを回避するための修正を行いました。

変更確認方法

  1. ブランチ bug/fix-unique-violation-cleanup をローカルに取り込む

  2. rails console でコンソールを立ち上げる

  3. 以下のコマンドを実行してユーザーを定義

    user = User.find_by(name: 'Hajime Tayo')
    
  4. 以下のコードを実行し、エラーが出ることを確認

    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
    
  5. 以下のコードを実行し、エラーが出ないでバリデーションが実行されていることを確認

    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

su-su-su-su avatar Aug 10 '24 11:08 su-su-su-su