lib/dsu/validators/entries_validator.rb in dsu-0.1.0.alpha.5 vs lib/dsu/validators/entries_validator.rb in dsu-1.0.0
- old
+ new
@@ -5,58 +5,69 @@
# https://guides.rubyonrails.org/active_record_validations.html#validates-with
module Dsu
module Validators
class EntriesValidator < ActiveModel::Validator
- include Dsu::Support::FieldErrors
+ include Support::FieldErrors
def validate(record)
- raise 'options[:fields] is not defined.' unless options.key? :fields
- raise 'options[:fields] is not an Array.' unless options[:fields].is_a? Array
- raise 'options[:fields] elements are not Symbols.' unless options[:fields].all?(Symbol)
+ unless record.entries.is_a?(Array)
+ record.errors.add(:entries_entry, 'is the wrong object type. ' \
+ "\"Array\" was expected, but \"#{record.entries.class}\" was received.")
+ end
- options[:fields].each do |field|
- entries = record.send(field)
+ validate_entry_types record
+ validate_unique_entry record
+ validate_entries record
+ end
- unless entries.is_a?(Array)
- record.errors.add(field, 'is the wrong object type. ' \
- "\"Array\" was expected, but \"#{entries.class}\" was received.")
- next
- end
+ private
- validate_entry_types field, entries, record
- validate_unique_entry_attr :uuid, field, entries, record
- validate_unique_entry_attr :description, field, entries, record
+ def validate_entry_types(record)
+ record.entries.each do |entry|
+ next if entry.is_a? Dsu::Models::Entry
+
+ record.errors.add(:entries_entry, 'entry Array element is the wrong object type. ' \
+ "\"Entry\" was expected, but \"#{entry.class}\" was received.",
+ type: Support::FieldErrors::FIELD_TYPE_ERROR)
end
end
- private
+ def validate_unique_entry(record)
+ return unless record.entries.is_a? Array
- def validate_entry_types(field, entries, record)
- entries.each do |entry|
- next if entry.is_a? Dsu::Models::Entry
+ entry_objects = record.entries.select { |entry| entry.is_a?(Dsu::Models::Entry) }
- record.errors.add(field, 'entry Array element is the wrong object type. ' \
- "\"Entry\" was expected, but \"#{entry.class}\" was received.",
- type: Dsu::Support::FieldErrors::FIELD_TYPE_ERROR)
+ descriptions = entry_objects.map(&:description)
+ return if descriptions.uniq.length == descriptions.length
- next
+ non_unique_descriptions = descriptions.select { |description| descriptions.count(description) > 1 }.uniq
+ if non_unique_descriptions.any?
+ record.errors.add(:entries_entry, 'contains a duplicate entry: ' \
+ "#{format_non_unique_descriptions(non_unique_descriptions)}.",
+ type: Support::FieldErrors::FIELD_DUPLICATE_ERROR)
end
end
- def validate_unique_entry_attr(attr, field, entries, record)
- return unless entries.is_a? Array
+ def validate_entries(record)
+ entries = record.entries
+ return if entries.none?
- entry_objects = entries.select { |entry| entry.is_a?(Dsu::Models::Entry) }
+ entries.each do |entry|
+ next if entry.valid?
- attrs = entry_objects.map(&attr)
- return if attrs.uniq.length == attrs.length
-
- non_unique_attrs = attrs.select { |attr| attrs.count(attr) > 1 }.uniq # rubocop:disable Lint/ShadowingOuterLocalVariable
- if non_unique_attrs.any?
- record.errors.add(field, "contains duplicate ##{attr}s: #{non_unique_attrs.join(', ')}.",
- type: Dsu::Support::FieldErrors::FIELD_DUPLICATE_ERROR)
+ entry.errors.each do |error|
+ record.errors.add(:entries_entry, error.full_message)
+ end
end
+ end
+
+ def format_non_unique_descriptions(non_unique_descriptions)
+ non_unique_descriptions.map { |description| "\"#{short_description(description)}\"" }.join(', ')
+ end
+
+ def short_description(description)
+ Models::Entry.short_description(string: description)
end
end
end
end