I'm working with an existing rails app, using postgresql. Its schema.rb file has id: :serial
for many, but not all, tables:
create_table "foos", id: :serial, force: :cascade do |t|
When I run rails db:migrate:reset
, id: :serial
is removed. We are all on the same version of postgres, but different OSes. I haven't exhaustively tested the behavior between machines, but I think there is a difference between machines.
The rails version is the same as it was when the project started.
The project did start with sqlite3. When I switch to that and regenerate the file, same behavior.
What could cause this option to be removed in my environment?
here's some code that is probably relevant:
update
rails db:migrate:reset
on colleague's machines, and I was wrong! their environments also remove id: :serial
.id: :serial
in schema.rb either.When you run rails db:migrate:reset
as opposed to rails db:reset
, the database schema is not loaded from schema.rb
but is instead reconstructed from all of your migrations. In migrations and schema files you do not need to specify an id
field, one is provided by default. However, starting with Rails 5.1, the default size of the id field was increased from INT
to BIGINT
for MySQL and from SERIAL
to BIGSERIAL
for PostgreSQL. So probably there is some interaction between your migrations, schema.rb
, and the actual schema in the database that is causing the id field to be treated as default (and omitted) in some cases and be explicitly specified in others, just due to the change in the default size. It's hard to guess at the source of the problem without seeing all the relevant files.
The answer is simply rails 5.0 vs 5.1 migrations. I had previously thought that the project started in 5.1, so I didin't test this. But then I dug deeper and discovered it started in 5.0, and experimentation shows that's the answer.
class SerialIdTest < ActiveRecord::Migration[5.0]
def change
create_table "test" do |t|
t.integer "foo_id"
t.string "foo_role"
end
end
end
create_table "test", id: :serial, force: :cascade do |t|
t.integer "foo_id"
t.string "foo_role"
end
# \d test
Table "public.test"
Column | Type | Modifiers
------------------+-------------------+-------------------------------------------------------
id | integer | not null default nextval('test_id_seq'::regclass)
foo_id | integer |
foo_role | character varying |
Indexes:
"test_pkey" PRIMARY KEY, btree (id)
class SerialIdTest < ActiveRecord::Migration[5.1]
def change
create_table "test" do |t|
t.integer "foo_id"
t.string "foo_role"
end
end
end
create_table "test", force: :cascade do |t|
t.integer "foo_id"
t.string "foo_role"
end
# \d test
Table "public.test"
Column | Type | Modifiers
------------------+-------------------+-------------------------------------------------------
id | bigint | not null default nextval('test_id_seq'::regclass)
foo_id | integer |
foo_role | character varying |
Indexes:
"test_pkey" PRIMARY KEY, btree (id)
class SerialIdTest < ActiveRecord::Migration[5.1]
def change
create_table "test", id: :serial do |t|
t.integer "foo_id"
t.string "foo_role"
end
end
end
create_table "test", id: :serial, force: :cascade do |t|
t.integer "foo_id"
t.string "foo_role"
end
# \d test
Table "public.test"
Column | Type | Modifiers
------------------+-------------------+-------------------------------------------------------
id | integer | not null default nextval('test_id_seq'::regclass)
foo_id | integer |
foo_role | character varying |
Indexes:
"test_pkey" PRIMARY KEY, btree (id)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With