Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails 3: Apply the same validation rules to multiple table fields

I have created a model with several fields that should accept the same data format (strings, but can be anything, FWIW). I'd like to apply the same validation rule to all those fields. Of course, I can just go ahead and copy/paste stuff, but that would be against DRY principle, and common sense too...

I guess this one is pretty easy, but I'm a Rails newcomer/hipster, so excuse-moi for a trivial question. =)

like image 845
aL3xa Avatar asked Mar 20 '12 20:03

aL3xa


3 Answers

So if you had say three fields to validate:

:first_name
:last_name
:age

And you wanted them all to be validated? So something like this:

validates_presence_of :first_name, :last_name, :age

Edit: There are numerous different validation methods in Rails )and they're wonderfully flexible). For the format of the field you can use validates_format_of, and then use a Regular Expression to match against it. Here's an example of matching an email:

validates_format_of :email, :with => /^([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/i

I'd check out the Active Record Validations and Callbacks guide; it provides comprehensive insight about a lot of the features Active Record provides in terms of validation. You can also check out the documentation here.

like image 66
Jon McIntosh Avatar answered Oct 17 '22 11:10

Jon McIntosh


If you are using any of the built-in validations (presence, length_of) you can apply a single validation to multiple attributes like this:

validates_presence_of :name, :email

If you have custom logic you can create a validator object to house the code and apply it individually

class EmailValidator < ActiveModel::EachValidator
  def validate_each(record, attribute, value)
    record.errors[attribute] << (options[:message] || "is not an email") unless
      value =~ /^([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/i
  end
end

def Person
  validates :home_email, :email => true
  validates :work_email, :email => true
end

see: http://thelucid.com/2010/01/08/sexy-validation-in-edge-rails-rails-3/

like image 5
Carlos Ramirez III Avatar answered Oct 17 '22 10:10

Carlos Ramirez III


In Rails 4 you can apply the same validation to multiple columns by using a loop:

[:beds, :baths].each do |column|
  validates column, allow_blank: true, length: { maximum: 25 }
end

Both beds and baths are validated using the same validations.

Edit:

In Rails 4.2 you can do this same thing by putting multiple symbols after the validates function call. Example:

validates :beds, :baths, allow_blank: true
like image 3
Ken Stipek Avatar answered Oct 17 '22 11:10

Ken Stipek