Is there a way to know if an attribute has a validation? Something like following:
Model.attribute.has_presence_validation?
Is there a way to know if an attribute has a validation? Something like following:
Model.attribute.has_presence_validation?
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
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)}
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.