rails serialized array validation
Asked Answered
P

2

6

I need to validate email saving in email_list. For validation I have EmailValidator. But I cannot figure out how to use it in pair of validates_each. Are there any other ways to make validations?

class A < ActiveRecord::Base
  serialize :email_list
  validates_each :email_list do |r, a, v|
    # what should it be here? 
    # EmailValidator.new(options).validate_each r, a, v
  end
end
Paronymous answered 2/6, 2014 at 8:53 Comment(4)
:email_list is an array containing emails and you want to be sure each email is a valid one or what?Blasted
yes, exactly. I need to validate every email and add error if anyone is invalidParonymous
the answer provided by @gwcoffey seems to do that.Blasted
main difficulty is related to 'if' condition. I cannot figure out how to use EmailValidator hereParonymous
A
2

I ended up with this: https://gist.github.com/amenzhinsky/c961f889a78f4557ae0b

You can write your own EmailValidator according to rails guide and use the ArrayValidator like:

validates :emails, array: { email: true }
Accursed answered 5/1, 2015 at 14:44 Comment(0)
T
5

validates_each is for validating multiple attributes. In your case you have one attribute, and you need to validate it in a custom way.

Do it like this:

class A < ActiveRecord::Base
   validate :all_emails_are_valid

   ...

   private
   def all_emails_are_valid
      unless self.email_list.nil?
         self.email_list.each do |email|
            if # email is valid -- however you want to do that
               errors.add(:email_list, "#{email} is not valid")
            end
         end
      end
   end
end

Note that you could also make a custom validator for this or put the validation in a proc on the validate call. See here.

Here's an example with a custom validator.

class A < ActiveRecord::Base

  class ArrayOfEmailsValidator < ActiveModel::EachValidator
    def validate_each(record, attribute, value)
      return if value.nil?
      value.each do |email|
        if # email is valid -- however you want to do that
          record.errors.add(attribute, "#{email} is not valid")
        end
      end
    end
  end

  validates :email_list, :array_of_emails => true

  ...

end

Of course you can put the ArrayOfEmailsValidator class in, i.e., lib/array_of_emails_validator.rb and load it where you need it. This way you can share the validator across models or even projects.

Transmitter answered 2/6, 2014 at 9:18 Comment(3)
I stick to if condition), what could it be using EmailValidator?Paronymous
I added a second example of a custom validatorTransmitter
Thanks for it. But I still can't find way to use EmailValidator. As it can have complicated logic, which cannot inserted to ArrayOfEmailsValidator directly. Is it possible to write 'if' code in details?Paronymous
A
2

I ended up with this: https://gist.github.com/amenzhinsky/c961f889a78f4557ae0b

You can write your own EmailValidator according to rails guide and use the ArrayValidator like:

validates :emails, array: { email: true }
Accursed answered 5/1, 2015 at 14:44 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.