Uncategorized

Railsでテストを作っていたら,”Minitest::UnexpectedError: ActiveRecord::RecordNotUnique: RuntimeError: UNIQUE constraint failed”が出てハマった

fjordbootcampのプラクティスでRailsのテストを作る課題をやっていたら、Minitest::UnexpectedError: ActiveRecord::RecordNotUnique: RuntimeError: UNIQUE constraint failed: relationships.follower_id, relationships.following_idというエラーにハマりました。
昨日までは問題なくテスト通っていたんですけどね。。

ちなみに解決策はtest/fixturesを確認して、重複を修正するだけでOKでした!

エラーコード

一応エラーコードを載せておきます。
ただ、早く解決策を知りたい場合は読み飛ばしてもらっても大丈夫です。

Minitest::UnexpectedError: ActiveRecord::RecordNotUnique: RuntimeError: UNIQUE constraint failed: relationships.follower_id, relationships.following_id
    /Users/tsukadaryou/.rbenv/versions/3.0.0/lib/ruby/gems/3.0.0/gems/sqlite3-1.4.2/lib/sqlite3/database.rb:305:in `exec_batch'
    /Users/tsukadaryou/.rbenv/versions/3.0.0/lib/ruby/gems/3.0.0/gems/sqlite3-1.4.2/lib/sqlite3/database.rb:305:in `execute_batch2'
    /Users/tsukadaryou/.rbenv/versions/3.0.0/lib/ruby/gems/3.0.0/gems/activerecord-6.1.0/lib/active_record/connection_adapters/sqlite3/database_statements.rb:122:in `block (2 levels) in execute_batch'
    /Users/tsukadaryou/.rbenv/versions/3.0.0/lib/ruby/gems/3.0.0/gems/activesupport-6.1.0/lib/active_support/dependencies/interlock.rb:48:in `block in permit_concurrent_loads'
    /Users/tsukadaryou/.rbenv/versions/3.0.0/lib/ruby/gems/3.0.0/gems/activesupport-6.1.0/lib/active_support/concurrency/share_lock.rb:187:in `yield_shares'
    /Users/tsukadaryou/.rbenv/versions/3.0.0/lib/ruby/gems/3.0.0/gems/activesupport-6.1.0/lib/active_support/dependencies/interlock.rb:47:in `permit_concurrent_loads'
    /Users/tsukadaryou/.rbenv/versions/3.0.0/lib/ruby/gems/3.0.0/gems/activerecord-6.1.0/lib/active_record/connection_adapters/sqlite3/database_statements.rb:121:in `block in execute_batch'
    /Users/tsukadaryou/.rbenv/versions/3.0.0/lib/ruby/gems/3.0.0/gems/activerecord-6.1.0/lib/active_record/connection_adapters/abstract_adapter.rb:697:in `block (2 levels) in log'
    /Users/tsukadaryou/.rbenv/versions/3.0.0/lib/ruby/gems/3.0.0/gems/activesupport-6.1.0/lib/active_support/concurrency/load_interlock_aware_monitor.rb:26:in `block (2 levels) in synchronize'
    /Users/tsukadaryou/.rbenv/versions/3.0.0/lib/ruby/gems/3.0.0/gems/activesupport-6.1.0/lib/active_support/concurrency/load_interlock_aware_monitor.rb:25:in `handle_interrupt'
    /Users/tsukadaryou/.rbenv/versions/3.0.0/lib/ruby/gems/3.0.0/gems/activesupport-6.1.0/lib/active_support/concurrency/load_interlock_aware_monitor.rb:25:in `block in synchronize'
    /Users/tsukadaryou/.rbenv/versions/3.0.0/lib/ruby/gems/3.0.0/gems/activesupport-6.1.0/lib/active_support/concurrency/load_interlock_aware_monitor.rb:21:in `handle_interrupt'
    /Users/tsukadaryou/.rbenv/versions/3.0.0/lib/ruby/gems/3.0.0/gems/activesupport-6.1.0/lib/active_support/concurrency/load_interlock_aware_monitor.rb:21:in `synchronize'
    /Users/tsukadaryou/.rbenv/versions/3.0.0/lib/ruby/gems/3.0.0/gems/activerecord-6.1.0/lib/active_record/connection_adapters/abstract_adapter.rb:696:in `block in log'
    /Users/tsukadaryou/.rbenv/versions/3.0.0/lib/ruby/gems/3.0.0/gems/activesupport-6.1.0/lib/active_support/notifications/instrumenter.rb:24:in `instrument'
    /Users/tsukadaryou/.rbenv/versions/3.0.0/lib/ruby/gems/3.0.0/gems/activerecord-6.1.0/lib/active_record/connection_adapters/abstract_adapter.rb:688:in `log'
    /Users/tsukadaryou/.rbenv/versions/3.0.0/lib/ruby/gems/3.0.0/gems/activerecord-6.1.0/lib/active_record/connection_adapters/sqlite3/database_statements.rb:120:in `execute_batch'
    /Users/tsukadaryou/.rbenv/versions/3.0.0/lib/ruby/gems/3.0.0/gems/activerecord-6.1.0/lib/active_record/connection_adapters/abstract/database_statements.rb:413:in `block (3 levels) in insert_fixtures_set'
    /Users/tsukadaryou/.rbenv/versions/3.0.0/lib/ruby/gems/3.0.0/gems/activerecord-6.1.0/lib/active_record/connection_adapters/abstract/database_statements.rb:320:in `block in transaction'
    /Users/tsukadaryou/.rbenv/versions/3.0.0/lib/ruby/gems/3.0.0/gems/activerecord-6.1.0/lib/active_record/connection_adapters/abstract/transaction.rb:310:in `block in within_new_transaction'
    /Users/tsukadaryou/.rbenv/versions/3.0.0/lib/ruby/gems/3.0.0/gems/activesupport-6.1.0/lib/active_support/concurrency/load_interlock_aware_monitor.rb:26:in `block (2 levels) in synchronize'
    /Users/tsukadaryou/.rbenv/versions/3.0.0/lib/ruby/gems/3.0.0/gems/activesupport-6.1.0/lib/active_support/concurrency/load_interlock_aware_monitor.rb:25:in `handle_interrupt'
    /Users/tsukadaryou/.rbenv/versions/3.0.0/lib/ruby/gems/3.0.0/gems/activesupport-6.1.0/lib/active_support/concurrency/load_interlock_aware_monitor.rb:25:in `block in synchronize'
    /Users/tsukadaryou/.rbenv/versions/3.0.0/lib/ruby/gems/3.0.0/gems/activesupport-6.1.0/lib/active_support/concurrency/load_interlock_aware_monitor.rb:21:in `handle_interrupt'
    /Users/tsukadaryou/.rbenv/versions/3.0.0/lib/ruby/gems/3.0.0/gems/activesupport-6.1.0/lib/active_support/concurrency/load_interlock_aware_monitor.rb:21:in `synchronize'
    /Users/tsukadaryou/.rbenv/versions/3.0.0/lib/ruby/gems/3.0.0/gems/activerecord-6.1.0/lib/active_record/connection_adapters/abstract/transaction.rb:308:in `within_new_transaction'
    /Users/tsukadaryou/.rbenv/versions/3.0.0/lib/ruby/gems/3.0.0/gems/activerecord-6.1.0/lib/active_record/connection_adapters/abstract/database_statements.rb:320:in `transaction'
    /Users/tsukadaryou/.rbenv/versions/3.0.0/lib/ruby/gems/3.0.0/gems/activerecord-6.1.0/lib/active_record/connection_adapters/abstract/database_statements.rb:412:in `block (2 levels) in insert_fixtures_set'
    /Users/tsukadaryou/.rbenv/versions/3.0.0/lib/ruby/gems/3.0.0/gems/activerecord-6.1.0/lib/active_record/connection_adapters/sqlite3_adapter.rb:202:in `disable_referential_integrity'
    /Users/tsukadaryou/.rbenv/versions/3.0.0/lib/ruby/gems/3.0.0/gems/activerecord-6.1.0/lib/active_record/connection_adapters/abstract/database_statements.rb:411:in `block in insert_fixtures_set'
    /Users/tsukadaryou/.rbenv/versions/3.0.0/lib/ruby/gems/3.0.0/gems/activerecord-6.1.0/lib/active_record/connection_adapters/abstract/database_statements.rb:523:in `with_multi_statements'
    /Users/tsukadaryou/.rbenv/versions/3.0.0/lib/ruby/gems/3.0.0/gems/activerecord-6.1.0/lib/active_record/connection_adapters/abstract/database_statements.rb:410:in `insert_fixtures_set'
    /Users/tsukadaryou/.rbenv/versions/3.0.0/lib/ruby/gems/3.0.0/gems/activerecord-6.1.0/lib/active_record/fixtures.rb:638:in `block in insert'
    /Users/tsukadaryou/.rbenv/versions/3.0.0/lib/ruby/gems/3.0.0/gems/activerecord-6.1.0/lib/active_record/fixtures.rb:629:in `each'
    /Users/tsukadaryou/.rbenv/versions/3.0.0/lib/ruby/gems/3.0.0/gems/activerecord-6.1.0/lib/active_record/fixtures.rb:629:in `insert'
    /Users/tsukadaryou/.rbenv/versions/3.0.0/lib/ruby/gems/3.0.0/gems/activerecord-6.1.0/lib/active_record/fixtures.rb:615:in `read_and_insert'
    /Users/tsukadaryou/.rbenv/versions/3.0.0/lib/ruby/gems/3.0.0/gems/activerecord-6.1.0/lib/active_record/fixtures.rb:567:in `create_fixtures'
    /Users/tsukadaryou/.rbenv/versions/3.0.0/lib/ruby/gems/3.0.0/gems/activerecord-6.1.0/lib/active_record/test_fixtures.rb:227:in `load_fixtures'
    /Users/tsukadaryou/.rbenv/versions/3.0.0/lib/ruby/gems/3.0.0/gems/activerecord-6.1.0/lib/active_record/test_fixtures.rb:120:in `setup_fixtures'
    /Users/tsukadaryou/.rbenv/versions/3.0.0/lib/ruby/gems/3.0.0/gems/activerecord-6.1.0/lib/active_record/test_fixtures.rb:10:in `before_setup'
    /Users/tsukadaryou/.rbenv/versions/3.0.0/lib/ruby/gems/3.0.0/gems/activesupport-6.1.0/lib/active_support/testing/setup_and_teardown.rb:40:in `before_setup'
/Users/tsukadaryou/.rbenv/versions/3.0.0/lib/ruby/gems/3.0.0/gems/sqlite3-1.4.2/lib/sqlite3/database.rb:305:in `exec_batch'
/Users/tsukadaryou/.rbenv/versions/3.0.0/lib/ruby/gems/3.0.0/gems/sqlite3-1.4.2/lib/sqlite3/database.rb:305:in `execute_batch2'
/Users/tsukadaryou/.rbenv/versions/3.0.0/lib/ruby/gems/3.0.0/gems/activerecord-6.1.0/lib/active_record/connection_adapters/sqlite3/database_statements.rb:122:in `block (2 levels) in execute_batch'
/Users/tsukadaryou/.rbenv/versions/3.0.0/lib/ruby/gems/3.0.0/gems/activesupport-6.1.0/lib/active_support/dependencies/interlock.rb:48:in `block in permit_concurrent_loads'
/Users/tsukadaryou/.rbenv/versions/3.0.0/lib/ruby/gems/3.0.0/gems/activesupport-6.1.0/lib/active_support/concurrency/share_lock.rb:187:in `yield_shares'
/Users/tsukadaryou/.rbenv/versions/3.0.0/lib/ruby/gems/3.0.0/gems/activesupport-6.1.0/lib/active_support/dependencies/interlock.rb:47:in `permit_concurrent_loads'
/Users/tsukadaryou/.rbenv/versions/3.0.0/lib/ruby/gems/3.0.0/gems/activerecord-6.1.0/lib/active_record/connection_adapters/sqlite3/database_statements.rb:121:in `block in execute_batch'
/Users/tsukadaryou/.rbenv/versions/3.0.0/lib/ruby/gems/3.0.0/gems/activerecord-6.1.0/lib/active_record/connection_adapters/abstract_adapter.rb:697:in `block (2 levels) in log'
/Users/tsukadaryou/.rbenv/versions/3.0.0/lib/ruby/gems/3.0.0/gems/activesupport-6.1.0/lib/active_support/concurrency/load_interlock_aware_monitor.rb:26:in `block (2 levels) in synchronize'
/Users/tsukadaryou/.rbenv/versions/3.0.0/lib/ruby/gems/3.0.0/gems/activesupport-6.1.0/lib/active_support/concurrency/load_interlock_aware_monitor.rb:25:in `handle_interrupt'
/Users/tsukadaryou/.rbenv/versions/3.0.0/lib/ruby/gems/3.0.0/gems/activesupport-6.1.0/lib/active_support/concurrency/load_interlock_aware_monitor.rb:25:in `block in synchronize'
/Users/tsukadaryou/.rbenv/versions/3.0.0/lib/ruby/gems/3.0.0/gems/activesupport-6.1.0/lib/active_support/concurrency/load_interlock_aware_monitor.rb:21:in `handle_interrupt'
/Users/tsukadaryou/.rbenv/versions/3.0.0/lib/ruby/gems/3.0.0/gems/activesupport-6.1.0/lib/active_support/concurrency/load_interlock_aware_monitor.rb:21:in `synchronize'
/Users/tsukadaryou/.rbenv/versions/3.0.0/lib/ruby/gems/3.0.0/gems/activerecord-6.1.0/lib/active_record/connection_adapters/abstract_adapter.rb:696:in `block in log'
/Users/tsukadaryou/.rbenv/versions/3.0.0/lib/ruby/gems/3.0.0/gems/activesupport-6.1.0/lib/active_support/notifications/instrumenter.rb:24:in `instrument'
/Users/tsukadaryou/.rbenv/versions/3.0.0/lib/ruby/gems/3.0.0/gems/activerecord-6.1.0/lib/active_record/connection_adapters/abstract_adapter.rb:688:in `log'
/Users/tsukadaryou/.rbenv/versions/3.0.0/lib/ruby/gems/3.0.0/gems/activerecord-6.1.0/lib/active_record/connection_adapters/sqlite3/database_statements.rb:120:in `execute_batch'
/Users/tsukadaryou/.rbenv/versions/3.0.0/lib/ruby/gems/3.0.0/gems/activerecord-6.1.0/lib/active_record/connection_adapters/abstract/database_statements.rb:413:in `block (3 levels) in insert_fixtures_set'
/Users/tsukadaryou/.rbenv/versions/3.0.0/lib/ruby/gems/3.0.0/gems/activerecord-6.1.0/lib/active_record/connection_adapters/abstract/database_statements.rb:320:in `block in transaction'
/Users/tsukadaryou/.rbenv/versions/3.0.0/lib/ruby/gems/3.0.0/gems/activerecord-6.1.0/lib/active_record/connection_adapters/abstract/transaction.rb:310:in `block in within_new_transaction'
/Users/tsukadaryou/.rbenv/versions/3.0.0/lib/ruby/gems/3.0.0/gems/activesupport-6.1.0/lib/active_support/concurrency/load_interlock_aware_monitor.rb:26:in `block (2 levels) in synchronize'
/Users/tsukadaryou/.rbenv/versions/3.0.0/lib/ruby/gems/3.0.0/gems/activesupport-6.1.0/lib/active_support/concurrency/load_interlock_aware_monitor.rb:25:in `handle_interrupt'
/Users/tsukadaryou/.rbenv/versions/3.0.0/lib/ruby/gems/3.0.0/gems/activesupport-6.1.0/lib/active_support/concurrency/load_interlock_aware_monitor.rb:25:in `block in synchronize'
/Users/tsukadaryou/.rbenv/versions/3.0.0/lib/ruby/gems/3.0.0/gems/activesupport-6.1.0/lib/active_support/concurrency/load_interlock_aware_monitor.rb:21:in `handle_interrupt'
/Users/tsukadaryou/.rbenv/versions/3.0.0/lib/ruby/gems/3.0.0/gems/activesupport-6.1.0/lib/active_support/concurrency/load_interlock_aware_monitor.rb:21:in `synchronize'
/Users/tsukadaryou/.rbenv/versions/3.0.0/lib/ruby/gems/3.0.0/gems/activerecord-6.1.0/lib/active_record/connection_adapters/abstract/transaction.rb:308:in `within_new_transaction'
/Users/tsukadaryou/.rbenv/versions/3.0.0/lib/ruby/gems/3.0.0/gems/activerecord-6.1.0/lib/active_record/connection_adapters/abstract/database_statements.rb:320:in `transaction'
/Users/tsukadaryou/.rbenv/versions/3.0.0/lib/ruby/gems/3.0.0/gems/activerecord-6.1.0/lib/active_record/connection_adapters/abstract/database_statements.rb:412:in `block (2 levels) in insert_fixtures_set'
/Users/tsukadaryou/.rbenv/versions/3.0.0/lib/ruby/gems/3.0.0/gems/activerecord-6.1.0/lib/active_record/connection_adapters/sqlite3_adapter.rb:202:in `disable_referential_integrity'
/Users/tsukadaryou/.rbenv/versions/3.0.0/lib/ruby/gems/3.0.0/gems/activerecord-6.1.0/lib/active_record/connection_adapters/abstract/database_statements.rb:411:in `block in insert_fixtures_set'
/Users/tsukadaryou/.rbenv/versions/3.0.0/lib/ruby/gems/3.0.0/gems/activerecord-6.1.0/lib/active_record/connection_adapters/abstract/database_statements.rb:523:in `with_multi_statements'
/Users/tsukadaryou/.rbenv/versions/3.0.0/lib/ruby/gems/3.0.0/gems/activerecord-6.1.0/lib/active_record/connection_adapters/abstract/database_statements.rb:410:in `insert_fixtures_set'
/Users/tsukadaryou/.rbenv/versions/3.0.0/lib/ruby/gems/3.0.0/gems/activerecord-6.1.0/lib/active_record/fixtures.rb:638:in `block in insert'
/Users/tsukadaryou/.rbenv/versions/3.0.0/lib/ruby/gems/3.0.0/gems/activerecord-6.1.0/lib/active_record/fixtures.rb:629:in `each'
/Users/tsukadaryou/.rbenv/versions/3.0.0/lib/ruby/gems/3.0.0/gems/activerecord-6.1.0/lib/active_record/fixtures.rb:629:in `insert'
/Users/tsukadaryou/.rbenv/versions/3.0.0/lib/ruby/gems/3.0.0/gems/activerecord-6.1.0/lib/active_record/fixtures.rb:615:in `read_and_insert'
/Users/tsukadaryou/.rbenv/versions/3.0.0/lib/ruby/gems/3.0.0/gems/activerecord-6.1.0/lib/active_record/fixtures.rb:567:in `create_fixtures'
/Users/tsukadaryou/.rbenv/versions/3.0.0/lib/ruby/gems/3.0.0/gems/activerecord-6.1.0/lib/active_record/test_fixtures.rb:227:in `load_fixtures'
/Users/tsukadaryou/.rbenv/versions/3.0.0/lib/ruby/gems/3.0.0/gems/activerecord-6.1.0/lib/active_record/test_fixtures.rb:120:in `setup_fixtures'
/Users/tsukadaryou/.rbenv/versions/3.0.0/lib/ruby/gems/3.0.0/gems/activerecord-6.1.0/lib/active_record/test_fixtures.rb:10:in `before_setup'
/Users/tsukadaryou/.rbenv/versions/3.0.0/lib/ruby/gems/3.0.0/gems/activesupport-6.1.0/lib/active_support/testing/setup_and_teardown.rb:40:in `before_setup'

プロセスは終了コード 0 で終了しました

原因は??

色々と調べていると、fixturesが関連してる?
Rails Tutorial: SQLite3::ConstraintException: UNIQUE constraint failed: users.email

follower_idとfollowing_idがユニークになってない!というエラ〜メッセージだったので、フォロー・フォロワー関連を扱っているtest/fixtures/relationships.ymlを確認します。

# Read about fixtures at https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html

one:
  following_id: 1
  follower_id: 1

two:
  following_id: 1
  follower_id: 1

oneとtwoのfollowing_idfollower_idが被っていますね💦
昨日まではこのエラーが出ていなかったので、DBをいじっているときに変更されてしまったのかもしれません。

ということで下記のように書き直しました。

# Read about fixtures at https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html

one:
  following_id: 1
  follower_id: 1

two:
  following_id: 2
  follower_id: 2

これで重複はなくなりました!
ではテストを実行します。

/bin/zsh -c "bash -c 'env RBENV_VERSION=3.0.0 /Users/tsukadaryou/.rbenv/libexec/rbenv exec bundle exec ruby -Itest /Applications/RubyMine.app/Contents/plugins/ruby/rb/testing/runner/minitest_runner.rb'"
Testing started at 14:48 ...

プロセスは終了コード 0 で終了しました

問題なくパスできました!