For adding check constraints until now with Rails, we had to execute raw SQL queries using migrations.
Example
Suppose we want to create a table for Book
model with a check constraint on price field that price should be greater than 100. The only way to do this earlier was to write a migration with a raw sql query after creating table as given below:
class CreateBooks < ActiveRecord::Migration
def change
create_table :books do |t|
t.string :name
t.integer :price
end
end
end
class AddConstraintToBooks < ActiveRecord::Migration
def up
execute "ALTER TABLE books ADD CONSTRAINT price_check CHECK (price > 100)"
end
def down
execute "ALTER TABLE books DROP CONSTRAINT price_check"
end
end
Moreover, this was an irreversible migration hence had to add it separately with up and down methods.
Solution? check_constraint
, :add_check_constraint
and remove_check_constraint
Rails 6.1 now allows adding check_constraint to rails migration when creating table as well as DSL to create check_constraints via migration after the table has been created.
Syntax for adding check_constraint at the time of table creation is:
create_table :table_name do |t|
...
t.check_constraint [constraint_name], [constraint]
end
Syntax for adding and removing check_constraint to an already existing table is:
add_check_constraint :table_name, :constraint_condition, name: "constraint_name"
remove_check_constraint :table_name, name: "constraint_name"
Notice that both add_check_constraint
and remove_check_constraint
are reversible.
Example:
In the previous Book
example.
Notice that we are adding check_constraint
when creating the books table itself:
class CreateBooks < ActiveRecord::Migration
def change
create_table :books do |t|
t.string :name
t.integer :price
t.check_constraint "price_check", "price > 100"
end
end
end
For adding a price_check
constraint to books
table through a separate migration:
class CreateBooks < ActiveRecord::Migration
def change
add_check_constraint :books, "price > 100", name: "price_check"
end
end
And for removing the price_check
constraint from books
table through a separate migration:
class CreateBooks < ActiveRecord::Migration
def change
remove_check_constraint :books, name: "price_check"
end
end