When we are running Rails migrations, it’s common to combine multiple changes into a single change_table block especially when we want to keep database schema in sync.
Before Rails 7.1
Previously the
validate_constraint
and
validate_check_constraint
was called outside of the
change_table
block to check constraint and its validations into two distinct steps
For example:
class AddNameColumnsAndConstraintToUser < ActiveRecord::Migration[7.0]
def change
change_table :user, bulk: true do |t|
t.string :first_name
t.string :last_name
t.check_constraint "first_name IS NOT NULL AND last_name IS NOT NULL",
name: "name_not_null", validate: false
end
validate_check_constraint :user, "name_not_null"
end
end
After
Rails 7.1 added the enhancement, we can now write cleaner migrations by combining column additions and constraint validations within a single change_table block.
def validate_constraint(*args)
@base.validate_constraint(name, *args)
end
def validate_check_constraint(*args)
@base.validate_check_constraint(name, *args)
end
With this change, we can write cleaner migrations by combining column additions and constraint validations within a single change_table block.
For example:
class AddUserDetailsToUsers < ActiveRecord::Migration[7.0]
def change
change_table :users, bulk: true do |t|
t.string :first_name
t.string :last_name
t.check_constraint "first_name IS NOT NULL AND last_name IS NOT NULL",
name: "name_not_null"
# Now Rails knows to delegate this method to validate the constraint
t.validate_check_constraint "name_not_null"
end
end
end