Class: SubsetValidator

Inherits:
ActiveModel::EachValidator
  • Object
show all
Defined in:
lib/subset_validator.rb

Constant Summary collapse

@@error_message =
'contains an invalid value'

Instance Method Summary collapse

Instance Method Details

#validate_each(record, attribute, value) ⇒ Object

Validate that the specified attribute’s value is a subset of another set.

Note that this works on more than just arrays, too. It’ll work on anything, provided that:

  • the attribute’s value can be anything that responds to #each ;

  • the set of valid values can be anything that responds to #include? .

Examples:

class User
  include ActiveModel::Validations

  attr_accessor :roles

  @@valid_roles = %w(admin manager developer)

  validates :roles, :subset => {:in => @@valid_roles}
end

u       = User.new
u.roles = %w(admin something_else)

u.valid?
 => false
u.errors
 => {:roles=>["contains an invalid value"]}

u.roles = %w(admin)
u.valid?
 => true


32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
# File 'lib/subset_validator.rb', line 32

def validate_each(record, attribute, value)
  unless options[:in].respond_to? :include?
    raise ArgumentError, 'An object with the method include? must be supplied as the :in option of the configuration hash'
  end

  unless value.respond_to? :each
    raise ArgumentError, 'The attribute being validated must respond to #each'
  end

  error_message = options[:message] || @@error_message

  value.each do |element|
    unless options[:in].include? element
      record.errors.add attribute, error_message
      break
    end
  end
end