Class: NestedAttributesOrderValidator

Inherits:
ActiveModel::EachValidator
  • Object
show all
Defined in:
lib/nested_attributes_validator/active_model/validations/nested_attributes_order_validator.rb

Instance Method Summary collapse

Instance Method Details

#validate_each(record, attribute, values) ⇒ Object



3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# File 'lib/nested_attributes_validator/active_model/validations/nested_attributes_order_validator.rb', line 3

def validate_each(record, attribute, values)
  fields = ([options[:fields]] || [:self]).flatten.map(&:to_s)

  h = values.inject({}){|ret, v| ret[v] = fields.map{|f| v.send(f)}; ret}
  if options[:ignore_nil]
    h = h.reject{|k, v| v.all?(&:nil?)}
  end
  if fields.size == 1
    h.keys.each {|k| h[k] = h[k].first}
  end

  h.each_cons(2) do |(v1, f1), (v2, f2)|
    condition = options[:condition] || lambda {|a, b| a < b}
    is_valid = condition.call(f1, f2)

    unless is_valid
      fields.each do |field|
        # set error to the parent record
        attribute_name = :"#{attributes.first}.#{options[:display_field] || field}"
        record.errors[attribute_name] << I18n.t('errors.messages.nested_attributes_invalid_order')
        record.errors[attribute_name].uniq!

        # also set error to the child record to apply "field_with_errors"
        v1.errors.add(field , nil)
        v2.errors.add(field , nil)
      end
    end
  end
end