Rails - 使用 PostgresQL 在数据库迁移中指定一个固定长度的列
Rails - Specify a fixed length column in DB migration with PostgresSQL
列修饰符中似乎只有:limit
,它指定了该列的最大长度。但是,如果我想指定准确的长度怎么办?例如手机号码必须有 11 位数字,所以我不希望用户输入无效号码。当然我也可以在模型逻辑甚至前端进行验证,但是在数据库级别添加约束似乎更安全。在 Rails 中有没有办法实现这一点?或者我是否必须使用特定于 Postgre 的命令。如果可以,怎么做?
谢谢!
Rails 本身只支持一组有限的约束。您可以通过 execute
运行 任意 SQL 命令,但是:
class CreateAddresses < ActiveRecord::Migration
def change
create_table(:addresses) do |t|
t.string :phone_number, null: false
end
execute "ALTER TABLE addresses ADD CONSTRAINT addresses_phone_length CHECK (length(phone_number) = 11)"
end
end
您可以为此使用 mv-core (https://github.com/vprokopchuk256/mv-core)。它允许您以类似于 Rails 中的方式定义数据库级验证。
例如,您的问题可能会通过两种方式得到解决gem:
- 作为预定义验证
def change
create_table :addresses do |t|
t.string :phone_number, length: 11
end
end
- 作为自定义验证
def change
create_table :addresses do |t|
t.string :phone_number, validates: 'TRIM(LENGTH({phone_number})) = 11'
end
end
- 作为自定义消息的预定义验证:
def change
create_table :addresses do |t|
t.string :phone_number,
validates: { length: { is: 11, message: 'should have length == 11' } }
end
end
如果需要,数据库验证可以升级到模型作为标准 ActiveModel 验证:
class Address < ActiveRecord::Base
enforce_migration_validations
end
因此,您将拥有标准的 ActiveRecord 验证行为
列修饰符中似乎只有:limit
,它指定了该列的最大长度。但是,如果我想指定准确的长度怎么办?例如手机号码必须有 11 位数字,所以我不希望用户输入无效号码。当然我也可以在模型逻辑甚至前端进行验证,但是在数据库级别添加约束似乎更安全。在 Rails 中有没有办法实现这一点?或者我是否必须使用特定于 Postgre 的命令。如果可以,怎么做?
谢谢!
Rails 本身只支持一组有限的约束。您可以通过 execute
运行 任意 SQL 命令,但是:
class CreateAddresses < ActiveRecord::Migration
def change
create_table(:addresses) do |t|
t.string :phone_number, null: false
end
execute "ALTER TABLE addresses ADD CONSTRAINT addresses_phone_length CHECK (length(phone_number) = 11)"
end
end
您可以为此使用 mv-core (https://github.com/vprokopchuk256/mv-core)。它允许您以类似于 Rails 中的方式定义数据库级验证。
例如,您的问题可能会通过两种方式得到解决gem:
- 作为预定义验证
def change
create_table :addresses do |t|
t.string :phone_number, length: 11
end
end
- 作为自定义验证
def change
create_table :addresses do |t|
t.string :phone_number, validates: 'TRIM(LENGTH({phone_number})) = 11'
end
end
- 作为自定义消息的预定义验证:
def change
create_table :addresses do |t|
t.string :phone_number,
validates: { length: { is: 11, message: 'should have length == 11' } }
end
end
如果需要,数据库验证可以升级到模型作为标准 ActiveModel 验证:
class Address < ActiveRecord::Base
enforce_migration_validations
end
因此,您将拥有标准的 ActiveRecord 验证行为