概要
原著者の許諾を得て翻訳・公開いたします。
- 英語記事: Rails 6.1 adds support for check constraints to database migrations | Saeloun Blog
- 原文公開日: 2021/01/08
- 著者: Dhiraj Mishra
- サイト: Saeloun Blog | Ruby on Rails Consulting Company based in San Francisco and Boston | Page 1 | Saeloun Blog
なお、該当のAPIドキュメントは以下です。
add_check_constraint
— ActiveRecord::ConnectionAdapters::SchemaStatementscheck_constraint
— ActiveRecord::ConnectionAdapters::SchemaStatementsremove_check_constraint
— ActiveRecord::ConnectionAdapters::SchemaStatements
Rails 6.1: CHECK制約のサポートをマイグレーションに追加(翻訳)
従来のRailsでは、ADD CONSTRAINT カラム名 CHECK 制約
を行うにはマイグレーションで生SQLを実行しなければなりませんでした。
例
Bookモデル用のテーブルを作成し、そのprice
フィールドに「価格は100より大きいこと」という制約を付けたいとします。従来は以下のように、テーブル作成後にマイグレーションで生SQLを書くしか方法がありませんでした。
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
しかもこのマイグレーションはそのままではロールバックできないので、up
メソッドとdown
メソッドを別々に書かなければいけません。
解決方法: check_constraint
、:add_check_constraint
、remove_check_constraint
Rails 6.1のマイグレーションにcheck_constraint
メソッドが追加され、テーブル作成時にDSLとしてcheck_constraint
を使うことも、テーブル作成後のマイグレーションで使うこともできるようになりました(#31323)。
テーブル作成時にcheck_constraint
を使う場合の構文は以下のとおりです。
create_table :table_name do |t|
...
t.check_constraint [constraint_name], [constraint]
end
既存のテーブルで制約を追加または削除するには、check_constraint
を以下の構文で用います。
add_check_constraint :table_name, :constraint_condition, name: "constraint_name"
remove_check_constraint :table_name, name: "constraint_name"
add_check_constraint
メソッドとremove_check_constraint
メソッドは、どちらもロールバック可能である点にご注目ください。
例:
先ほどのBook
モデルの例を用います。
以下のマイグレーションでは、books
テーブル自身を作成するときにcheck_constraint
メソッドを追加していることにご注目ください。
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
別のマイグレーションで、books
テーブルにprice_check
制約を追加する場合は以下のように書きます。
class CreateBooks < ActiveRecord::Migration
def change
add_check_constraint :books, "price > 100", name: "price_check"
end
end
別のマイグレーションで、price_check
制約をbooks
テーブルから削除するには以下のように書きます。
class CreateBooks < ActiveRecord::Migration
def change
remove_check_constraint :books, name: "price_check"
end
end