Reputation: 4746
Is there a way to know if an attribute has a validation? Something like following:
Model.attribute.has_presence_validation?
Upvotes: 9
Views: 3546
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
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
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