今回の問題
- Rails/Active Recordで新しいレコードを作成しようとすると、エラーが出てしまう
PG::Error: ERROR: duplicate key value violates unique constraint "addresses_pkey"
DETAIL: Key (id)=(2) already exists.
原因
ActiveRecordでレコードを作成するとき、primary_keyがid
になっている時はAddress.create(name: "toyota")
とidを指定せずに作成しても自動でidを付与してくれる。シーケンスも自動インクリメントしてくれる。
ただし、idの順序がすでに指定されてある場合などにAddress.create(id: 12, name: "suzuki")
とidを指定しレコード作成した場合、次のレコード作成時にシーケンスが自動インクリメントされない。そのため、DETAIL: Key (id)=(2) already exists.
というエラーが出てしまう。
解決方法
SQLを発行して、シーケンスを訂正する。下記のSQLを実行すると、テーブル内のレコードからidの最大値+1
した値をシーケンスとして保存してくれる。
# Addressテーブルのidのシーケンスを直す場合の例
SELECT setval('addresses_id_seq', coalesce((SELECT MAX(id)+1 FROM addresses), 1), false)
Railsアプリ内上記SQLを実行する場合は下記のように書く
ActiveRecord::Base.connection.execute("SELECT setval('addresses_id_seq', coalesce((SELECT MAX(id)+1 FROM addresses), 1), false)")