Module: Form::ActiveModel::Validations

Defined in:
lib/reform/form/active_model/validations.rb

Overview

AM::Validations for your form. Provides ::validates, ::validate, #validate, and #valid?.

Most of this file contains unnecessary wiring to make ActiveModel’s error message magic work. Since Rails still thinks it’s a good idea to do things like object.class.human_attribute_name, we have some hacks in here to provide that. If it doesn’t work for you, don’t blame us.

Defined Under Namespace

Classes: Group, Result, Validator

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.included(includer) ⇒ Object



14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# File 'lib/reform/form/active_model/validations.rb', line 14

def self.included(includer)
  includer.instance_eval do
    include Reform::Form::ActiveModel

    class << self
      extend Uber::Delegates
      # # Hooray! Delegate translation back to Reform's Validator class which contains AM::Validations.
      delegates :active_model_really_sucks, :human_attribute_name, :lookup_ancestors, :i18n_scope # Rails 3.1.

      def validation_group_class
        Group
      end

      # this is to allow calls like Form::human_attribute_name (note that this is on the CLASS level) to be resolved.
      # those calls happen when adding errors in a custom validation method, which is defined on the form (as an instance method).
      def active_model_really_sucks
        Class.new(Validator).tap do |v|
          v.model_name = model_name
        end
      end
    end
  end # ::included
end

Instance Method Details

#custom_errorsObject



55
56
57
58
59
60
61
62
63
64
65
# File 'lib/reform/form/active_model/validations.rb', line 55

def custom_errors
  # required to keep update the ActiveModel::Errors#details used to test for
  # added errors ActiveModel::Errors#added? and needs to be inside this block!
  super.each do |custom_error|
    errors = custom_error.errors
    # CustomError build always the errors with an hash where the value is an array
    errors.values.first.each do |value|
      @amv_errors.add(errors.keys.first, value)
    end
  end
end

#errors(*args) ⇒ Object

Problem with this method is, it’s being used in two completely different contexts: Once to add errors in validations, and second to expose errors for presentation.



51
52
53
# File 'lib/reform/form/active_model/validations.rb', line 51

def errors(*args)
  @amv_errors
end

#initializeObject



44
45
46
47
# File 'lib/reform/form/active_model/validations.rb', line 44

def initialize(*)
  super
  @amv_errors = ActiveModel::Errors.new(self)
end

#read_attribute_for_validation(name) ⇒ Object

The concept of “composition” has still not arrived in Rails core and they rely on 400 methods being available in one object. This is why we need to provide parts of the I18N API in the form.



40
41
42
# File 'lib/reform/form/active_model/validations.rb', line 40

def read_attribute_for_validation(name)
  send(name)
end

#validate!(params, pointers = []) ⇒ Object



67
68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/reform/form/active_model/validations.rb', line 67

def validate!(params, pointers=[])
  @amv_errors = ActiveModel::Errors.new(self)

  super.tap do
    # @fran: super ugly hack thanks to the shit architecture of AMV. let's drop it in 3.0 and move on!
    all_errors = @result.to_results
    nested_errors = @result.instance_variable_get(:@failure)

    @result = Reform::Contract::Result.new(all_errors, [nested_errors].compact)

    @amv_errors = Result::ResultErrors.new(@result, self, @result.success?, @amv_errors)
  end
  @result
end