Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails/ActiveModel passing arguments to EachValidator

I have a very generic validator and I want to pass it arguments.

Here is an example model:

class User
  include Mongoid::Document

  field :order_type
  has_many :orders, inverse_of :user
  validates: orders, generic: true #i want to pass argument (order_type)

  field :task_type
  has_many :tasks, inverse_of :user
  validates: tasks, generic: true #i want to pass argument (task_type)
end

and Example validator:

class GenericValidator < ActiveModel::EachValidator
  def validate_each(object, attribute, value)
    if some_validation?(object)
      object.errors[attribute] << (options[:message] || "is not formatted properly") 
    end
  end
end

Is there any way to pass arguments to the validator dependant on which field it is validating?

thanks

like image 881
GTDev Avatar asked Oct 24 '12 01:10

GTDev


1 Answers

I wasn't aware of this either, but if you want to pass an argument, then pass a hash to generic: instead of true. This post details the exact process you're wanting to follow:

class User
  include Mongoid::Document

  field :order_type
  has_many :orders, inverse_of :user
  validates: orders, generic: { :order_type => order_type }

  field :task_type
  has_many :tasks, inverse_of :user
  validates: tasks, generic: { :task_type => task_type }
end

GenericValidator should now have access to both arguments you're wanting to pass in validation: options[:order_type] and options[:task_type].

It might make more sense, however, to divide these up into two validators, with both inheriting the shared behavior as mentioned by dpassage:

  class User
    include Mongoid::Document

    field :order_type
    has_many :orders, inverse_of :user
    validates: orders, order: { type: order_type }

    field :task_type
    has_many :tasks, inverse_of :user
    validates: tasks, task: { type: task_type }
  end
like image 60
clekstro Avatar answered Nov 11 '22 23:11

clekstro