Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Same custom validation for several fields in Rails

I have four date_time fields in my model in Rails app. I want to apply the same validation method to them, so that only a valid date time could be accepted. Validation method is from earlier question on stack overflow:

  validate :datetime_field_is_valid_datetime

  def datetime_field_is_valid_datetime
    errors.add(:datetime_field, 'must be a valid datetime') if ((DateTime.parse(datetime_field) rescue ArgumentError) == ArgumentError) && !datetime_field.nil? && !datetime_field.blank?
  end

Is there more elegant way to validate these fields, other than defining four exactly same methods for every DateTime field?

like image 337
Nikita Barsukov Avatar asked Feb 21 '11 16:02

Nikita Barsukov


2 Answers

Best solution is to create your own validator:

class MyModel < ActiveRecord::Base
  include ActiveModel::Validations

  class DateValidator < ActiveModel::EachValidator
    def validate_each(record, attribute, value)
      record.errors[attribute] << "must be a valid datetime" unless (DateTime.parse(value) rescue nil)
    end
  end
  validates :datetime_field, :presence => true, :date => true
  validates :another_datetime_field, :presence => true, :date => true
  validates :third_datetime_field, :presence => true, :date => true
end

UPD

you can share same validations this way:

  validates :datetime_field, :another_datetime_field, :third_datetime_field, :presence => true, :date => true
like image 66
fl00r Avatar answered Nov 04 '22 07:11

fl00r


def self.validate_is_valid_datetime(field)
  validate do |model|
    if model.send("#{field}?") && ((DateTime.parse(model.send(field)) rescue ArgumentError) == ArgumentError)
      model.errors.add(field, 'must be a valid datetime')
    end
  end
end

validate_is_valid_datetime :datetime_field
like image 3
Alex Lang Avatar answered Nov 04 '22 07:11

Alex Lang