4

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!

Ivan Chaer
  • 6,980
  • 1
  • 38
  • 48
Benjamin Cbr
  • 536
  • 4
  • 13

2 Answers2

4

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
Leantraxxx
  • 4,506
  • 3
  • 38
  • 56
  • Thanks for the answer. I went for the custom validator option in the end. Enumerize actually stores the value as a list with an empty string `[""]`, and this is not handled properly by the gem for now. There is a PR open about this topic. – Benjamin Cbr Jul 06 '16 at 06:49
2

This is actually a bug that should be fixed in a later version of Enumerize (See https://github.com/brainspec/enumerize/pull/226).

In the meantime, you can use a custom validator as a workaround (See Leantraxx's answer).

Benjamin Cbr
  • 536
  • 4
  • 13