Skip to content

Instantly share code, notes, and snippets.

@wojtha
Last active June 10, 2016 08:18
Show Gist options
  • Select an option

  • Save wojtha/a0c6a7a1dbdce8737903f4b9bb200d30 to your computer and use it in GitHub Desktop.

Select an option

Save wojtha/a0c6a7a1dbdce8737903f4b9bb200d30 to your computer and use it in GitHub Desktop.
UniquenessValidator to be used outside the model (e.g. in form object)
# Class UniquenessValidator adds 'model' option to the options so it can be used
# outside the model.
#
# See http://stackoverflow.com/a/14671979/807647
#
# Example:
#
# class SignupForm
# include ActiveModel::Model
# attr_reader :email
# validates :email,
# uniqueness: { case_sensitive: false, model: User, attribute: 'name' }
# end
#
class UniquenessValidator < ActiveRecord::Validations::UniquenessValidator
def validate_each(record, attribute, value)
# UniquenessValidator can't be used outside of ActiveRecord instances, here
# we return the exact same error, unless the 'model' option is given.
if !options[:model] && !record.class.ancestors.include?(ActiveRecord::Base)
raise ArgumentError, "Unknown validator: 'UniquenessValidator'"
# If we're inside an ActiveRecord class, and `model` isn't set, use the
# default behaviour of the validator.
elsif !options[:model]
super
# Custom validator options. The validator can be called in any class, as
# long as it includes `ActiveModel::Validations`. You can tell the validator
# which ActiveRecord based class to check against, using the `model`
# option. Also, if you are using a different attribute name, you can set the
# correct one for the ActiveRecord class using the `attribute` option.
else
record_orig, attribute_orig = record, attribute
attribute = options[:attribute].to_sym if options[:attribute]
record = options[:model].new(attribute => value)
super
if record.errors.any?
options_orig = options.except(:case_sensitive, :scope).merge(value: value)
record_orig.errors.add(attribute_orig, :taken, options_orig)
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment