0
votes

I need to apply validation to a Model so that 2 integer values in the record, minimum and maximum, form an inclusive range (ex. 2 and 3 are ok, but 4 and 1 are not). From what I understand, since I need to validate 2 values against each other in the same record, I have to use ActiveModel::Validator (and not ActiveModel::EachValidator). So, I try the following:

Model (app/models/position.rb):

class Position < ActiveRecord::Base
  validates_with InclusiveRangeValidator
end

Validator (app/lib/validators/inclusive_range_validator.rb):

class InclusiveRangeValidator < ActiveModel::Validator
  def validate(record)
    record.errors[:base] << "#{record.minimum} and #{record.maximum} do not form a valid inclusive range." unless record.minimum < record.maximum
  end
end

I've read that Rails 3.0.5 doesn't automatically load the lib directory anymore, so I added this line in config/application.rb:

config.autoload_path += %W({config.root}/lib)

And then I reset the rails server so it'll take the change to config/application.rb. I run my unit tests, which tries to exercise the model to prove this validation works. I get this error:

uninitialized constant: Position::InclusiveRangeValidator (NameError)

What I think is happening is that Rails is not recognizing/finding my custom validator class, and so it assumes InclusiveRangeValidator is a constant in the class that it's referenced in. But, I thought the change I made to config/application.rb would put my validator in the load path so that it would be available.

I've gone through the other posts on StackOverflow and didn't come up with a solution, and I've read the API docs on validators, to no avail. I've got to be doing something simple and stupid, but I can't see what the issue is. Any help?

EDIT: After more searching, I discovered that I don't need a custom validator at all, as I can accomplish the same goal with this:

validates :minimum, :numericality => {:greater_than_or_equal_to => 0 }
validates :maximum, :numericality => {:greater_than => :minimum }

However, the question still remains as to why Rails can't locate the custom validation class.

1

1 Answers

2
votes

Once, I changed the line in application.rb to:

config.autoload_paths += %W[#{config.root}/lib/validators/]

Rails was able to find the right path to load my custom validator. I made the mistake of assuming Rails would automatically recurse the directory structure, this is evidently not the case.