el_quick
el_quick

Reputation: 4746

How to check if an attribute has a presence validation in Ruby on Rails

Is there a way to know if an attribute has a validation? Something like following:

Model.attribute.has_presence_validation?

Upvotes: 9

Views: 3546

Answers (3)

niborg
niborg

Reputation: 419

Combining some of the points in the other answers, I would have thought the following approach was most straightforward (Rails 4.2.7):

class Model < ActiveRecord::Base
  validates ... # Whatever your validation are

  def self.presence_required_attrs
    validators.select do |v|
      v.is_a?(ActiveRecord::Validations::PresenceValidator)
    end.map(&:attributes).flatten
  end
end

It's then as easy as:

Model.presence_required_attrs.include?(:my_attribute)

Edit:

More comprehensive solution I think is just having a helper or controller method:

def validated_attrs_for(model, validation)
    if validation.is_a?(String) || validation.is_a?(Symbol)
      klass = 'ActiveRecord::Validations::' \
              "#{validation.to_s.camelize}Validator"
      validation = klass.constantize
    end
    model.validators
         .select { |v| v.is_a?(validation) }
         .map(&:attributes)
         .flatten
end

Used:

validated_attrs_for(Model, :presence).include?(:my_attribute)

Just double check that the various validators (:presence, :uniqueness, etc.) correctly correspond to the appropriate Validator class -- I'm pretty sure they do, but haven't looked recently.

Upvotes: 3

lacco
lacco

Reputation: 892

For me, the following code is working (it is basically checking if any validator for given field is an instance of the presence validator):

MyModel.validators_on(:my_attribute).any?{|validator| validator.kind_of?(ActiveModel::Validations::PresenceValidator)}

Upvotes: 2

Abubakar
Abubakar

Reputation: 1032

Well not sure about simplest solution but I achieved this functionality with quite complexity. Maybe someone come up with some simpler solution. Here is the code which worked perfectly for me.

I get all the validations on a model, chose presence validations(ActiveRecord::Validations::PresenceValidator) and then select all of their attributes and used include to check attribute(:your_attribute)presence in this array

Model.validators.collect{|validation| validation if validation.class==ActiveRecord::Validations::PresenceValidator}.compact.collect(&:attributes).flatten.include? :your_attribute

you can change compare statement

validation.class==ActiveRecord::Validations::PresenceValidator

to get all other types validation i.e uniqueness etc

Upvotes: 9

Related Questions