PostgreSQLとRailsでシーケンスを手動で上げる
通常RailsのActiveRecordでレコードを作成するときは
User.create(name: "なまぽ", email: "namapo@mailaddress.com")
などとして作成し、テーブルのprimary_keyがidになっている場合には
自動でidを付与してシーケンスも自動インクリメントしてくれるので、
コードを書いている時に、idに関する考慮をあまりしなくてもいい仕組みになっているよ。
migrateなどで、テーブルを作成した場合にも特に指定がなければ
idのカラムを自動で作成してくれるし、さらにidのprimary_key指定もやってくれる。
例外として、idの順序やidそのものに意味がある場合には稀に
User.create(id: 1, name: "なまぽ1", email: "namapo1@mailaddress.com")
みたいに、idを指定してレコードを作成する場面があるかもしれない。
上みたいに、idを指定した場合にはシーケンスが自動でインクリメントしないので、
次に
User.create(name: "なまぽ2", email: "namapo2@mailaddress.com")
のように、次のレコードをid指定しないで作成した場合にエラーで怒られてレコードが作成できない。
PG::UniqueViolation: ERROR: duplicate key value violates unique constraint "users_pkey" DETAIL: Key (id)=(1) already exists.
こんな時には手動でシーケンスを上げてあげる必要がある。
SELECT setval('users_id_seq', coalesce((SELECT MAX(id)+1 FROM users), 1), false)
このSQLを実行することで、現在テーブルに格納されているレコードのidの最大値を取得して、
それに + 1したものをシーケンスとして保存してくれます。
うえのコードをRails上から呼び出す場合には
ActiveRecord::Base.connection.execute("SELECT setval('users_id_seq', coalesce((SELECT MAX(id)+1 FROM users), 1), false)")
してあげれば良しです。
ActiveRecord::Base.connection.execute()
の引数に任意のSQLを記述すれば実行できる