Jef*_*eff 30 ruby mysql ruby-on-rails database-migration
我需要在我的Rails应用程序中的现有表中添加一个新的整数列.该列只能有值1,2,3,所以我想在表/列中添加一个检查约束.如何在Rails迁移中指定此约束?
Nil*_*esh 46
Rails迁移不提供任何添加约束的方法,但您仍然可以通过迁移来实现,但是将实际的SQL传递给execute()
创建迁移文件:
ruby script/generate Migration AddConstraint
Run Code Online (Sandbox Code Playgroud)
现在,在迁移文件中:
class AddConstraint < ActiveRecord::Migration
def self.up
execute "ALTER TABLE table_name ADD CONSTRAINT check_constraint_name CHECK (check_column_name IN (1, 2, 3) )"
end
def self.down
execute "ALTER TABLE table_name DROP CONSTRAINT check_constraint_name"
end
end
Run Code Online (Sandbox Code Playgroud)
Mar*_*n13 16
所以现在,用于添加将整数列值限制为 1、2 和 3 的检查约束的迁移可以编写如下:
class AddConstraint < ActiveRecord::Migration
def up
add_check_constraint :table_name, 'check_column_name IN (1, 2, 3)', name: 'check_constraint_name'
end
def down
remove_check_constraint :table_name, name: 'check_constraint_name'
end
end
Run Code Online (Sandbox Code Playgroud)
这是相对 PR 的链接,您可以在其中找到有关add_check_constraint
和 的更多详细信息remove_check_constraint
。
小智 5
您可以使用 Migration Validators gem 来完成。在此处查看详细信息:https : //github.com/vprokopchuk256/mv-core
使用该 gem,您将能够在 db 级别定义包含验证:
def change
change_table :table_name do |t|
t.integer :column_name, inclusion: [1, 2, 3]
end
end
Run Code Online (Sandbox Code Playgroud)
此外,您可以定义如何定义验证,甚至应该显示错误消息:
def change
change_table :posts do |t|
t.integer :priority,
inclusion: { in: [1, 2, 3],
as: :trigger,
message: "can't be anything else than 1, 2, or 3" }
end
end
Run Code Online (Sandbox Code Playgroud)
您甚至可以升级从迁移到模型的验证:
class Post < ActiveRecord::Base
enforce_migration_validations
end
Run Code Online (Sandbox Code Playgroud)
然后迁移中的验证定义也将定义为模型中的 ActiveModel 验证:
Post.new(priority: 3).valid?
=> true
Post.new(priority: 4).valid?
=> false
Post.new(priority: 4).errors.full_messages
=> ["Priority can't be anything else than 1, 2, or 3"]
Run Code Online (Sandbox Code Playgroud)
我刚刚为此发布了一个 gem:active_record-postgres-constraints。正如那里的自述文件所描述的那样,您可以将它与 db/schema.rb 文件一起使用,并且它在迁移中添加了对以下方法的支持:
create_table TABLE_NAME do |t|
# Add columns
t.check_constraint conditions
# conditions can be a String, Array or Hash
end
add_check_constraint TABLE_NAME, conditions
remove_check_constraint TABLE_NAME, CONSTRAINT_NAME
Run Code Online (Sandbox Code Playgroud)
请注意,此时仅支持 postgres。