Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ruby class evaluation, validates_inclusion_of with dynamic data

If I have an ActiveRecord model as follows

class Foo < ActiveRecord::Base
  validates_inclusion_of :value, :in => self.allowed_types

  def self.allowed_types
    # some code that returns an enumerable
  end
end

This doesn't work because the allowed_types method hasn't been defined at the time where the validation is evaluated. All the fixes I can think of basically all revolve around moving the method definition above the validation so that it's available when needed.

I appreciate that this may be more of a coding style question than anything (I want all my validations at the top of the model and methods at the bottom) but I feel there should be some kind of solution to this, possibly involving lazy evaluation of the initial model load?

is what I want to do even possible? Should I just be defining the method above the validation or is there a better validation solution to acheive what I want.

like image 896
eightbitraptor Avatar asked Aug 18 '11 10:08

eightbitraptor


1 Answers

You should be able to use the lambda syntax for this purpose. Perhaps like this:

class Foo < ActiveRecord::Base
  validates_inclusion_of :value, :in => lambda { |foo| foo.allowed_types }

  def allowed_types
    # some code that returns an enumerable
  end
end

This way it will evaluate the lambda block at every validation and pass the instance of Foo to the block. It will then return the value from allowed_types in that instance so that it can be validated dynamically.

Also note that I removed self. from the allowed_types method declaration because that would create a class method instead of an instance method which is what you want here.

like image 114
DanneManne Avatar answered Oct 11 '22 07:10

DanneManne