-
Notifications
You must be signed in to change notification settings - Fork 138
Description
Description
I encountered a problem while migrating our app which uses ridgepole from Rails 6 to Rails 7.
I also found how to avoid this problem on user side so I am gonna post it here in case someone like me encounters it later.
I think this problem can be considered as a bug of ridgepole but since there is a way to avoid it it probably can be considered as pretty minor?
Suppose I have the following configuration in Rails 6 application:
# Gemfile
ruby "3.0.2"
gem "activerecord", "6.1.7"
gem "mysql2", "0.5.4"
gem "ridgepole", "1.2.0"
# schema
create_table :records do |t|
t.datetime :created_at_6, precision: 6
t.datetime :created_at_3, precision: 3
t.datetime :created_at_0
end
If I execute it with ridgepole it creates the following MySQL table:
-- Server version 8.0.23
CREATE TABLE `records` (
`id` bigint NOT NULL AUTO_INCREMENT,
`created_at_6` datetime(6) DEFAULT NULL,
`created_at_3` datetime(3) DEFAULT NULL,
`created_at_0` datetime DEFAULT NULL,
PRIMARY KEY (`id`)
)
Now I want to migrate my application to Rails 7 so I change the configuration to the following (I specified precision: nil for created_at_0 according to this):
# Gemfile
ruby "3.0.2"
gem "activerecord", "7.0.4.2"
gem "mysql2", "0.5.4"
gem "ridgepole", "1.2.0"
# schema
create_table :records do |t|
t.datetime :created_at_6, precision: 6
t.datetime :created_at_3, precision: 3
t.datetime :created_at_0, precision: nil
end
Now I run bundle exec ridgepole -a --verbose and this is what I get in return:
Apply `db/schemas/records.schema`
# Parse DSL
# Load tables
# records
# Compare definitions
# records
{:definition=>
{"created_at_0"=>{:options=>{:precision=>nil}, :type=>:datetime},
"created_at_3"=>{:options=>{:precision=>3}, :type=>:datetime},
- "created_at_6"=>{:options=>{}, :type=>:datetime}},
- :options=>{:charset=>"utf8", :collation=>"utf8_unicode_ci"}}
+ "created_at_6"=>{:options=>{:precision=>6}, :type=>:datetime}},
+ :options=>{}}
...
# Update schema
-- change_column("records", "created_at_6", :datetime, {:precision=>6, :null=>true, :default=>nil, :unsigned=>false, :comment=>nil})
-> 0.0096s
And it tries to update column created_at_6 every time I run this command to precision: 6 even though it's already precision: 6.
If I do an export here is what I get:
create_table "records", charset: "utf8", collation: "utf8_unicode_ci", force: :cascade do |t|
t.datetime "created_at_6"
t.datetime "created_at_3", precision: 3
t.datetime "created_at_0", precision: nil
end
This happens because now Rails dumper removes precision: 6 from the result it gets from the database because it considers it unnecessary (it's precision: 6 by default since Rails 7). So the only way to get rid of this unnecessary change for me is to change the schema according to the above removing precision: 6.
So, this can be avoided but I think at the very least this requires a comment in the Readme. Or, maybe ideally, a fix? After all, I wanted to keep precision: 6 specified in the schema explicitly for better readability so that the readers of the schema would not need to remember the differences in behaviour between Rails 6 and Rails 7. But I understand it might be too much effort to fix.