ruby-on-railsruby-on-rails-4

Custom validator based on Association value in Rails


My application has 3 Models (Foo, Bar and Baz)

class Foo
  has_many :bars

class Bar
  belongs_to :foo
  has_many   :bazs

class Baz
  belongs_to :bar

I'm trying to find the most intuitive way to validate a attribute in Baz (price), against limits set in Foo ( :min_price and :max_price ). Price in the Baz model must be between the limits set by Foo.

Currently I am trying to implement it using a custom PriceLimitValidator:

class PriceLimitValidator < ActiveModel::Validator
  def validate(record)
    unless ( record.price <= record.bar.foo.max_price && record.price >= record.bar.foo.min_price )
      record.errors[:price] << 'Price limit exceeded!'
    end
  end
end

This results in a NilClass error and frankly doesn't feel like the simplest solution.

Any tips for a rails beginner?


Solution

  • Rails provides spiffy validations based on the Ruby range capabilities right out of the box.

    For instance:

    validates_numericality_of :width, less_than: ->(person) { person.height }, :greater_than... etc. } 
    

    The complete spec with its myriad options is here:
    https://api.rubyonrails.org/v8.0/classes/ActiveModel/Validations/HelperMethods.html#method-i-validates_numericality_of