diff options
author | Shinya Maeda <shinya@gitlab.com> | 2017-07-03 16:59:57 +0900 |
---|---|---|
committer | Shinya Maeda <shinya@gitlab.com> | 2017-07-05 18:36:19 +0900 |
commit | c99f8e8884d98bacb2d6f157a8265cbc05df73a3 (patch) | |
tree | 51df7c4755e08cc6165188f775e32c2d5a6fc4d8 /app/validators | |
parent | cd6aa92207452ead4d2130ac12aa4bb1a18438cc (diff) | |
download | gitlab-ce-c99f8e8884d98bacb2d6f157a8265cbc05df73a3.tar.gz |
Implement uniqueness_of_in_memory_validator
Diffstat (limited to 'app/validators')
-rw-r--r-- | app/validators/uniqueness_of_in_memory_validator.rb | 37 |
1 files changed, 37 insertions, 0 deletions
diff --git a/app/validators/uniqueness_of_in_memory_validator.rb b/app/validators/uniqueness_of_in_memory_validator.rb new file mode 100644 index 00000000000..84e88b2eb76 --- /dev/null +++ b/app/validators/uniqueness_of_in_memory_validator.rb @@ -0,0 +1,37 @@ +# UniquenessOfInMemoryValidator +# +# This validtor is designed for especially the following condition +# - Use `accepts_nested_attributes_for :xxx` in a parent model +# - Use `validates :xxx, uniqueness: { scope: :xxx_id }` in a child model +# +# Inspired by https://stackoverflow.com/a/2883129/2522666 +module ActiveRecord + class Base + # Validate that the the objects in +collection+ are unique + # when compared against all their non-blank +attrs+. If not + # add +message+ to the base errors. + def validate_uniqueness_of_in_memory(collection, attrs, message) + hashes = collection.inject({}) do |hash, record| + key = attrs.map { |a| record.send(a).to_s }.join + if key.blank? || record.marked_for_destruction? + key = record.object_id + end + hash[key] = record unless hash[key] + hash + end + + if collection.length > hashes.length + self.errors.add(*message) + end + end + end +end + +class UniquenessOfInMemoryValidator < ActiveModel::Validator + def validate(record) + record.validate_uniqueness_of_in_memory( + record.public_send(options[:collection]), + options[:attrs], + options[:message]) + end +end |