Skip to content

Instantly share code, notes, and snippets.

@tlux
Last active December 16, 2015 09:29
Show Gist options
  • Save tlux/5413554 to your computer and use it in GitHub Desktop.
Save tlux/5413554 to your computer and use it in GitHub Desktop.
Compare Validator (ActiveModel)
# validates :password_approval, comparison: { to: :password }
# - or -
# validates :password_approval, comparison: { to: :password, is: :equal_to }
class ComparisonValidator < ActiveModel::EachValidator
OPERATOR_MAPPINGS = {
equal_to: :==,
greater_than: :>,
greater_than_or_equal_to: :>=,
less_than: :<,
less_than_or_equal_to: :<=
}
def initialize(options = {})
raise ArgumentError, ':to option must be defined' unless options[:to]
options[:is] ||= OPERATOR_MAPPINGS.keys.first
raise ArgumentError, "unknown comparison operator: #{options[:is]}" unless OPERATOR_MAPPINGS.key?(options[:is])
super(options)
end
def validate_each(record, attribute, value)
other_value = record.send(options[:to])
operator = options[:is]
unless value.send(OPERATOR_MAPPINGS[operator], other_value)
interpolations = options.merge(value: value, other_attribute_name: record.class.human_attribute_name(options[:to]), other_value: other_value)
record.errors.add(attribute, :"compared_#{operator}", interpolations)
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment