summaryrefslogtreecommitdiff
path: root/app/validators
diff options
context:
space:
mode:
authorShinya Maeda <shinya@gitlab.com>2017-07-06 00:23:28 +0900
committerShinya Maeda <shinya@gitlab.com>2017-07-06 00:23:28 +0900
commitdafc34179488d54776e80b8604513184720985cd (patch)
tree534ffedf025a31aeb74f2b21d4bf1a85f543b23d /app/validators
parent951dd04871a9be0bb83eac09883c130ca63cabdc (diff)
downloadgitlab-ce-dafc34179488d54776e80b8604513184720985cd.tar.gz
Revert "Implement Ci::NestedUniquenessValidator"
This reverts commit 8f0a2b6d780347a5ce258ac1a6a6902ce9695ca1.
Diffstat (limited to 'app/validators')
-rw-r--r--app/validators/uniqueness_of_in_memory_validator.rb37
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