Last active
June 10, 2016 08:18
-
-
Save wojtha/a0c6a7a1dbdce8737903f4b9bb200d30 to your computer and use it in GitHub Desktop.
UniquenessValidator to be used outside the model (e.g. in form object)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # 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