Mel
Mel

Reputation: 2685

Limit integer size in Rails migration

How do I specify a limit on an integer size in a Rails 4 migration? (My database is PostgreSQL.)

I have fields for phone_number, which should be 8 digits long. If I specify :limit => 8, then that is byte size rather than the length of the numbers.

Is there a way to do this?

Upvotes: 6

Views: 4549

Answers (2)

mu is too short
mu is too short

Reputation: 434665

You're going about this all wrong. A phone number is not a number at all, a phone number is a string that contains (mostly) digit characters. You don't do anything numeric – such as arithmetic – with phone numbers so they're not numbers, they're strings.

Make your phone_number column a string of length eight:

t.string :phone_number, limit: 8

and clean it up and validate the format in your model:

before_validation :clean_up_phone_number
validates :phone_number,
  format:    { with: /\A\d{8}\z/ },
  length:    { maximum: 8 },
  allow_nil: true

def clean_up_phone_number
  # Do whatever you want or need to strip out spaces, hyphens, etc. in here
end

Or better with PostgreSQL, don't worry about the size in the database at all and use t.string :phone_number. The size limit just adds pointless overhead and using a plain varchar rather than a varchar(8) makes it easier to allow for different phone number formats (area codes, extensions, international numbers, ...) later.

Upvotes: 10

Valera Prokopchuk
Valera Prokopchuk

Reputation: 126

Or you can do it with mv-core gem (https://github.com/vprokopchuk256/mv-core) right in a migration in this way (syntax is almost identical to AciveModel::Validations one):

def change
  update_table :users do |table|
    t.string :phone_number, 
             validates: { length: 8, 
                          format: /\A\d{8}\z/,
                          allow_blank: true, 
                          allow_nil: true }
  end
end

And then bubble up that validation to your model:

class User < ActiveRecord::Base
  enforce_migration_validations
end

By default your validation will be defined as CHECK constraint for PostgreSQL. But you can change that to trigger constraint, for ex. See details in the documentation.

Upvotes: 0

Related Questions