Rails - 使用PostgresQL在数据库迁移中指定固定长度的列

时间:2015-02-21 10:00:43

标签: ruby-on-rails postgresql activerecord rails-activerecord rails-migrations

似乎在列修饰符中只有:limit,它指定了此列的最大长度。但是,如果我想指定长度准确怎么办?例如,手机号码必须有11位数字,因此我不希望用户输入无效号码。当然我也可以在模型逻辑甚至前端进行验证,但是在DB级别添加约束似乎更安全。有没有办法在Rails中实现这一目标?或者我必须使用Postgre特定的命令。如果是这样,怎么样?

谢谢!

2 个答案:

答案 0 :(得分:1)

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

答案 1 :(得分:0)

您可以使用mv-core(https://github.com/vprokopchuk256/mv-core)。它允许您以类似于Rails中的方式定义数据库级验证。

例如,您的问题可能会通过两种方式解决:

  1. 作为预定义验证
  2. def change
      create_table :addresses do |t|
        t.string :phone_number, length: 11
      end
    end
    
    1. 作为自定义验证
    2. def change
        create_table :addresses do |t|
          t.string :phone_number, validates: 'TRIM(LENGTH({phone_number})) = 11'
        end
      end
      
      1. 使用自定义消息进行预定义验证:
      2. 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验证行为