Access class methods from inclusion validation
Asked Answered
T

4

11

I would like to include a class method as my options when using the inclusion validation:

class Search < ActiveRecord::Base

  attribute :foo, Array
  validates :foo, inclusion: class_method_options

  def self.class_method_options
   ['foo', 'bar']
  end
end

However I get undefined method 'class_method_options' for Search:Class (NoMethodError).

I tried Googling for the solution, but just found how to create a custom validation. I don't need a whole new validation, I just want to use the standard Rails inclusion validator. How can I access class_method_options from the inclusion validation?

Tenacious answered 21/8, 2014 at 1:54 Comment(0)
E
11

It's just not defined yet.

class Search < ActiveRecord::Base
  def self.class_method_options
   ['foo', 'bar']
  end

  attribute :foo, Array
  validates :foo, inclusion: class_method_options

end

That would work or you can do:

class Search < ActiveRecord::Base
  class_method_options = ['foo', 'bar']

  attribute :foo, Array
  validates :foo, inclusion: class_method_options

end
Epigrammatize answered 21/8, 2014 at 3:20 Comment(2)
Wouldn't the method name need to be a symbol?Amund
@RichPeck, No in this case your just calling it at the class level. As I said below, inclusion-in takes an enumerable, or a proc that returns and enumerable. In this case there is no rails magic that calls a method for you based on a symbol.Epigrammatize
M
3

You have to do like this

class Search < ActiveRecord::Base

  attribute :foo, Array
  validates :foo, inclusion: {in: :class_method_options }

  def class_method_options
   ['foo', 'bar']
  end
end
Manos answered 21/8, 2014 at 2:13 Comment(1)
This doesn't actually work. You have to pass an enumerable or a proc that returns an enumerable. This may work if you change it to { in: &:class_method_options }, but I haven't tested it. More about inclusion validation here: apidock.com/rails/ActiveModel/Validations/HelperMethods/…Epigrammatize
M
3

Given :in accepts Proc, I ended up with

validates :foo, inclusion: { in: Proc.new { |search| search.class.class_method_options } }
Makedamakefast answered 25/4, 2017 at 11:6 Comment(0)
U
0

You can use a lambda too, like so:

validates :foo, inclusion: { in: -> { class_method_options } }

When doing it that way you don't need to have it defined before the call to validates.

Undersexed answered 21/6, 2023 at 20:59 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.