Search code examples
ruby-on-railsrubyenumerize

How to validate presence of an array using Enumerize?


I'm trying to implement to validations on a given model array-like field, using the Enumerize Gem. I want to:

  • validate that all the elements of a list belong to a given subset, using Enumerize
  • validate that the list is not empty (using validates :field, presence: true)

It seems that when I provide a list containing an empty string, the presence validator fails. See this example.

class MyModel
  include ActiveModel::Model
  extend Enumerize

  enumerize :cities, in: %w(Boston London Berlin Paris), multiple: true
  validates :cities, presence: true
end


# Does not behave as expected
a = MyModel.new(cities: [""])
a.cities.present?  # => false
a.valid?  # => true, while it should be false.

It seems to work in some other cases (for instance when you provide a non empty string that is not in the Enum). For instance

# Behaves as expected
a = MyModel.new(cities: ["Dublin"])
a.cities.present?  # => false
a.valid?  # => false

Is there a workaround available to be able to use both Enumerize validation and ActiveModel presence validation?

Thanks!


Solution

  • The enumerize gem is saving your multiple values as an string array. Something like this: "[\"Boston\"]". So, with an empty array you have: "[]". The presencevalidator uses blank? method to check if the value is present or not. "[]".blank? returns false obviously.

    So, you can try some alternatives:

    Option 1:

    validates :cities, inclusion: { in: %w(Boston London Berlin Paris) }
    

    Option 2:

    Add a custom validator

    validate :ensure_valid_cities
    
    def ensure_valid_cities
      errors.add(:cities, "invalid") unless cities.values.empty?
    end