Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails validating values in array

In my Schedule model I want to add some validation to the :wdays field, which is an int[]. I only want values 0..6 to be valid

Valid

Schedule.wdays = [0,1,6]

Invalid

Schedule.wdays = [0,1,10]

I tried using

validates :wdays, inclusion: { in: [0, 1, 2, 3, 4, 5, 6] }

and

validates :wdays, inclusion: { in: 0..6 }

but neither works

What is the proper way to validate the values in an array in your model?

like image 473
bsiddiqui Avatar asked Nov 11 '13 17:11

bsiddiqui


2 Answers

I don't think that default Rails validators will do the trick here, you can do this though:

validate :validate_wdays

def validate_wdays
  if !wdays.is_a?(Array) || wdays.any?{|d| !(0..6).include?(d)}
    errors.add(:wdays, :invalid)
  end
end
like image 111
mechanicalfish Avatar answered Jan 01 '23 21:01

mechanicalfish


I'm not certain whether there are easier ways to handle this within the existing Rails validation structure. You've got an odd case that the validators weren't really built to handle. You might need to write a custom validator for something like this (assuming an existing validation extension gem isn't available). Something like this:

class ArrayInRangeValidator < ActiveModel::EachValidator
  def validate_each(record, attribute, valueArray)
    valueArray.each do |value|
      record.errors.add "#{attribute} - #{value}", (options[:message] || "is not in the acceptable range") unless (1..6).include?(value)
    end
  end
end

and then in your model:

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

    validates :wdays, :presence => true, :array_in_range => true

    ... other model stuff
end
like image 43
Paul Richter Avatar answered Jan 01 '23 20:01

Paul Richter