Introduction
In rails we are using migrations for performing database structure/schema modifications.
While doing so, we may end with many unsafe migrations. We shall go for strong_migrations
gem to make sure we write safe migrations.
It is also helpful to force the entire team to follow it as a best practice.
Step: 1 Add strong_migrations to Gemfile
gem 'strong_migrations'
Note: Do not add the gem under any group.
$ bundle install
$ rails generate strong_migrations:install
Step 2: checking the strong migrations
$ rails g scaffold User name:string{50} email
$ rake db:migrate
Adding column with default value
$ rails g migration add_status_to_users status:integer
update db/migrate/20200615103121_add_status_to_users.rb
class AddStatusToUsers < ActiveRecord::Migration[6.0]
def change
add_column :users, :status, :integer, default: 1
end
end
$ rake db:migrate
When we attempt to migrate the above migration it throws error as follows
rake aborted!
StandardError: An error has occurred, all later migrations canceled:
=== Dangerous operation detected #strong_migrations ===
Adding a column with a non-null default causes the entire table to be rewritten.
Instead, add the column without a default value, then change the default.
class AddStatusToUsers < ActiveRecord::Migration[6.0]
def up
add_column :users, :status, :integer
change_column_default :users, :status, 1
end
def down
remove_column :users, :status
end
end
Then backfill the existing rows in the Rails console or a separate migration with disable_ddl_transaction!.
class BackfillAddStatusToUsers < ActiveRecord::Migration[6.0]
disable_ddl_transaction!
def up
User.unscoped.in_batches do |relation|
relation.update_all status: 1
sleep(0.01)
end
end
end
strong_migrations
not only report the issue, it gives the suggestions as well, which is one of the most important notable feature.
Top comments (0)