active_interaction 4.1.0 → 5.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (77) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +128 -1
  3. data/README.md +63 -28
  4. data/lib/active_interaction/array_input.rb +77 -0
  5. data/lib/active_interaction/base.rb +14 -98
  6. data/lib/active_interaction/concerns/active_recordable.rb +3 -3
  7. data/lib/active_interaction/concerns/missable.rb +2 -2
  8. data/lib/active_interaction/errors.rb +6 -88
  9. data/lib/active_interaction/exceptions.rb +47 -0
  10. data/lib/active_interaction/filter/column.rb +59 -0
  11. data/lib/active_interaction/filter/error.rb +40 -0
  12. data/lib/active_interaction/filter.rb +44 -53
  13. data/lib/active_interaction/filters/abstract_date_time_filter.rb +9 -6
  14. data/lib/active_interaction/filters/abstract_numeric_filter.rb +7 -3
  15. data/lib/active_interaction/filters/array_filter.rb +34 -6
  16. data/lib/active_interaction/filters/boolean_filter.rb +4 -3
  17. data/lib/active_interaction/filters/date_filter.rb +1 -1
  18. data/lib/active_interaction/filters/date_time_filter.rb +1 -1
  19. data/lib/active_interaction/filters/decimal_filter.rb +1 -1
  20. data/lib/active_interaction/filters/float_filter.rb +1 -1
  21. data/lib/active_interaction/filters/hash_filter.rb +23 -15
  22. data/lib/active_interaction/filters/integer_filter.rb +1 -1
  23. data/lib/active_interaction/filters/interface_filter.rb +12 -12
  24. data/lib/active_interaction/filters/object_filter.rb +9 -3
  25. data/lib/active_interaction/filters/record_filter.rb +21 -11
  26. data/lib/active_interaction/filters/string_filter.rb +1 -1
  27. data/lib/active_interaction/filters/symbol_filter.rb +1 -1
  28. data/lib/active_interaction/filters/time_filter.rb +4 -4
  29. data/lib/active_interaction/hash_input.rb +43 -0
  30. data/lib/active_interaction/input.rb +23 -0
  31. data/lib/active_interaction/inputs.rb +157 -46
  32. data/lib/active_interaction/locale/en.yml +0 -1
  33. data/lib/active_interaction/locale/fr.yml +0 -1
  34. data/lib/active_interaction/locale/it.yml +0 -1
  35. data/lib/active_interaction/locale/ja.yml +0 -1
  36. data/lib/active_interaction/locale/pt-BR.yml +0 -1
  37. data/lib/active_interaction/modules/validation.rb +6 -17
  38. data/lib/active_interaction/version.rb +1 -1
  39. data/lib/active_interaction.rb +43 -36
  40. data/spec/active_interaction/array_input_spec.rb +166 -0
  41. data/spec/active_interaction/base_spec.rb +15 -240
  42. data/spec/active_interaction/concerns/active_modelable_spec.rb +3 -3
  43. data/spec/active_interaction/concerns/active_recordable_spec.rb +7 -7
  44. data/spec/active_interaction/concerns/hashable_spec.rb +8 -8
  45. data/spec/active_interaction/concerns/missable_spec.rb +9 -9
  46. data/spec/active_interaction/concerns/runnable_spec.rb +34 -32
  47. data/spec/active_interaction/errors_spec.rb +60 -43
  48. data/spec/active_interaction/{filter_column_spec.rb → filter/column_spec.rb} +3 -10
  49. data/spec/active_interaction/filter_spec.rb +6 -6
  50. data/spec/active_interaction/filters/abstract_date_time_filter_spec.rb +2 -2
  51. data/spec/active_interaction/filters/abstract_numeric_filter_spec.rb +2 -2
  52. data/spec/active_interaction/filters/array_filter_spec.rb +99 -16
  53. data/spec/active_interaction/filters/boolean_filter_spec.rb +12 -11
  54. data/spec/active_interaction/filters/date_filter_spec.rb +32 -27
  55. data/spec/active_interaction/filters/date_time_filter_spec.rb +34 -29
  56. data/spec/active_interaction/filters/decimal_filter_spec.rb +20 -18
  57. data/spec/active_interaction/filters/file_filter_spec.rb +7 -7
  58. data/spec/active_interaction/filters/float_filter_spec.rb +19 -17
  59. data/spec/active_interaction/filters/hash_filter_spec.rb +16 -18
  60. data/spec/active_interaction/filters/integer_filter_spec.rb +24 -22
  61. data/spec/active_interaction/filters/interface_filter_spec.rb +105 -82
  62. data/spec/active_interaction/filters/object_filter_spec.rb +52 -36
  63. data/spec/active_interaction/filters/record_filter_spec.rb +61 -39
  64. data/spec/active_interaction/filters/string_filter_spec.rb +7 -7
  65. data/spec/active_interaction/filters/symbol_filter_spec.rb +6 -6
  66. data/spec/active_interaction/filters/time_filter_spec.rb +57 -34
  67. data/spec/active_interaction/hash_input_spec.rb +58 -0
  68. data/spec/active_interaction/i18n_spec.rb +22 -17
  69. data/spec/active_interaction/inputs_spec.rb +167 -23
  70. data/spec/active_interaction/integration/array_interaction_spec.rb +3 -7
  71. data/spec/active_interaction/modules/validation_spec.rb +8 -31
  72. data/spec/spec_helper.rb +8 -0
  73. data/spec/support/concerns.rb +2 -2
  74. data/spec/support/filters.rb +27 -51
  75. data/spec/support/interactions.rb +4 -4
  76. metadata +40 -91
  77. data/lib/active_interaction/filter_column.rb +0 -57
@@ -47,34 +47,34 @@ module ActiveInteraction
47
47
  "constant #{const_name.inspect} does not exist"
48
48
  end
49
49
 
50
- def matches?(object)
51
- return false if object.nil?
52
- return matches_methods?(object) if options.key?(:methods)
50
+ def matches?(value)
51
+ return false if value == nil # rubocop:disable Style/NilComparison
52
+ return matches_methods?(value) if options.key?(:methods)
53
53
 
54
54
  const = from
55
- if checking_class_inheritance?(object, const)
56
- class_inherits_from?(object, const)
55
+ if checking_class_inheritance?(value, const)
56
+ class_inherits_from?(value, const)
57
57
  else
58
- singleton_ancestor?(object, const)
58
+ singleton_ancestor?(value, const)
59
59
  end
60
60
  rescue NoMethodError
61
61
  false
62
62
  end
63
63
 
64
- def matches_methods?(object)
65
- options[:methods].all? { |method| object.respond_to?(method) }
64
+ def matches_methods?(value)
65
+ options[:methods].all? { |method| value.respond_to?(method) }
66
66
  end
67
67
 
68
- def checking_class_inheritance?(object, from)
69
- object.is_a?(Class) && from.is_a?(Class)
68
+ def checking_class_inheritance?(value, from)
69
+ value.is_a?(Class) && from.is_a?(Class)
70
70
  end
71
71
 
72
72
  def class_inherits_from?(klass, inherits_from)
73
73
  klass != inherits_from && klass.ancestors.include?(inherits_from)
74
74
  end
75
75
 
76
- def singleton_ancestor?(object, from)
77
- object.class != from && object.singleton_class.ancestors.include?(from)
76
+ def singleton_ancestor?(value, from)
77
+ value.class != from && value.singleton_class.ancestors.include?(from)
78
78
  end
79
79
  end
80
80
  end
@@ -38,19 +38,25 @@ module ActiveInteraction
38
38
  end
39
39
 
40
40
  def matches?(value)
41
+ return false if value == nil # rubocop:disable Style/NilComparison
42
+
41
43
  value.class <= klass
42
44
  rescue NoMethodError
43
45
  false
44
46
  end
45
47
 
46
48
  def convert(value)
47
- converter(value).tap do |result|
48
- raise InvalidValueError if result.nil?
49
+ result = converter(value)
50
+
51
+ if result.nil?
52
+ [value, Filter::Error.new(self, :invalid_type)]
53
+ else
54
+ [result, nil]
49
55
  end
50
56
  rescue StandardError => e
51
57
  raise e if e.is_a?(InvalidConverterError)
52
58
 
53
- raise InvalidValueError
59
+ [value, Filter::Error.new(self, :invalid_type)]
54
60
  end
55
61
 
56
62
  def converter(value)
@@ -4,7 +4,9 @@ module ActiveInteraction
4
4
  class Base # rubocop:disable Lint/EmptyClass
5
5
  # @!method self.record(*attributes, options = {})
6
6
  # Creates accessors for the attributes and ensures that values passed to
7
- # the attributes are the correct class.
7
+ # the attributes are the correct class. Blank strings passed in will be
8
+ # treated as `nil` and the `finder` will not be called.
9
+
8
10
  #
9
11
  # @!macro filter_method_params
10
12
  # @option options [Class, String, Symbol] :class (use the attribute name)
@@ -44,20 +46,28 @@ module ActiveInteraction
44
46
  end
45
47
 
46
48
  def convert(value)
47
- finder = options.fetch(:finder, :find)
48
- find(klass, value, finder)
49
- end
49
+ return [nil, nil] if blank_string?(value)
50
50
 
51
- def find(klass, value, finder)
52
- result = klass.public_send(finder, value)
51
+ finder = options.fetch(:finder, :find)
52
+ result = find(klass, value, finder)
53
53
 
54
- raise InvalidValueError if result.nil?
54
+ if result.nil?
55
+ [value, Filter::Error.new(self, :invalid_type)]
56
+ else
57
+ [result, nil]
58
+ end
59
+ end
55
60
 
56
- result
57
- rescue StandardError => e
58
- raise e if e.is_a?(InvalidConverterError)
61
+ def blank_string?(value)
62
+ value.is_a?(String) && value.blank?
63
+ rescue NoMethodError # BasicObject
64
+ false
65
+ end
59
66
 
60
- raise InvalidValueError
67
+ def find(klass, value, finder)
68
+ klass.public_send(finder, value)
69
+ rescue StandardError
70
+ nil
61
71
  end
62
72
  end
63
73
  end
@@ -38,7 +38,7 @@ module ActiveInteraction
38
38
 
39
39
  def convert(value)
40
40
  if value.respond_to?(:to_str)
41
- value.to_str
41
+ [value.to_str, nil]
42
42
  else
43
43
  super
44
44
  end
@@ -26,7 +26,7 @@ module ActiveInteraction
26
26
 
27
27
  def convert(value)
28
28
  if value.respond_to?(:to_sym)
29
- value.to_sym
29
+ [value.to_sym, nil]
30
30
  else
31
31
  super
32
32
  end
@@ -6,9 +6,9 @@ module ActiveInteraction
6
6
  # Creates accessors for the attributes and ensures that values passed to
7
7
  # the attributes are Times. Numeric values are processed using `at`.
8
8
  # Strings are processed using `parse` unless the format option is
9
- # given, in which case they will be processed with `strptime`. If
10
- # `Time.zone` is available it will be used so that the values are time
11
- # zone aware.
9
+ # given, in which case they will be processed with `strptime`. Blank
10
+ # strings are treated as a `nil` value. If `Time.zone` is available it
11
+ # will be used so that the values are time zone aware.
12
12
  #
13
13
  # @!macro filter_method_params
14
14
  # @option options [String] :format parse strings using this format string
@@ -59,7 +59,7 @@ module ActiveInteraction
59
59
  value = value.to_int if value.respond_to?(:to_int)
60
60
 
61
61
  if value.is_a?(Numeric)
62
- klass.at(value)
62
+ [klass.at(value), nil]
63
63
  else
64
64
  super
65
65
  end
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveInteraction
4
+ # Represents a processed hash input.
5
+ class HashInput < Input
6
+ # @private
7
+ def initialize(filter, value: nil, error: nil, children: {})
8
+ super(filter, value: value, error: error)
9
+
10
+ @children = children
11
+ end
12
+
13
+ # @overload children
14
+ # Child inputs if nested filters are used.
15
+ #
16
+ # @return [Hash{ Symbol => Input, ArrayInput, HashInput }]
17
+ attr_reader :children
18
+
19
+ # Any errors that occurred during processing.
20
+ #
21
+ # @return [Filter::Error]
22
+ def errors
23
+ return @errors if defined?(@errors)
24
+
25
+ return @errors = super if @error
26
+
27
+ child_errors = get_errors(children)
28
+
29
+ return @errors = super if child_errors.empty?
30
+
31
+ @errors ||=
32
+ child_errors.map do |error|
33
+ Filter::Error.new(error.filter, error.type, name: :"#{@filter.name}.#{error.name}")
34
+ end.freeze
35
+ end
36
+
37
+ private
38
+
39
+ def get_errors(children)
40
+ children.values.flat_map(&:errors)
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveInteraction
4
+ # Represents a processed input.
5
+ class Input
6
+ # @private
7
+ def initialize(filter, value: nil, error: nil)
8
+ @filter = filter
9
+ @value = value
10
+ @error = error
11
+ end
12
+
13
+ # The processed input value.
14
+ attr_reader :value
15
+
16
+ # Any errors that occurred during processing.
17
+ #
18
+ # @return [Filter::Error]
19
+ def errors
20
+ @errors ||= Array(@error)
21
+ end
22
+ end
23
+ end
@@ -1,24 +1,23 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'forwardable'
4
+
3
5
  module ActiveInteraction
4
6
  # Holds inputs passed to the interaction.
5
- class Inputs < DelegateClass(Hash)
6
- class << self
7
- # matches inputs like "key(1i)"
8
- GROUPED_INPUT_PATTERN = /
9
- \A
10
- (?<key>.+) # extracts "key"
11
- \((?<index>\d+)i\) # extracts "1"
12
- \z
13
- /x.freeze
14
- private_constant :GROUPED_INPUT_PATTERN
7
+ class Inputs
8
+ include Enumerable
9
+ extend Forwardable
15
10
 
16
- # @private
17
- def keys_for_group?(keys, group_key)
18
- search_key = /\A#{group_key}\(\d+i\)\z/
19
- keys.any? { |key| search_key.match?(key) }
20
- end
11
+ # matches inputs like "key(1i)"
12
+ GROUPED_INPUT_PATTERN = /
13
+ \A
14
+ (?<key>.+) # extracts "key"
15
+ \((?<index>\d+)i\) # extracts "1"
16
+ \z
17
+ /x.freeze
18
+ private_constant :GROUPED_INPUT_PATTERN
21
19
 
20
+ class << self
22
21
  # Checking `syscall` is the result of what appears to be a bug in Ruby.
23
22
  # https://bugs.ruby-lang.org/issues/15597
24
23
  # @private
@@ -34,47 +33,159 @@ module ActiveInteraction
34
33
  !Object.private_method_defined?(name)
35
34
  )
36
35
  end
36
+ end
37
37
 
38
- # @param inputs [Hash, ActionController::Parameters, ActiveInteraction::Inputs] Attribute values to set.
39
- #
40
- # @private
41
- def process(inputs)
42
- normalize_inputs!(inputs)
43
- .stringify_keys
44
- .sort
45
- .each_with_object({}) do |(k, v), h|
46
- next if reserved?(k)
47
-
48
- if (group = GROUPED_INPUT_PATTERN.match(k))
49
- assign_to_grouped_input!(h, group[:key], group[:index], v)
50
- else
51
- h[k.to_sym] = v
52
- end
53
- end
38
+ # @private
39
+ def initialize(raw_inputs, base)
40
+ @base = base
41
+ @normalized_inputs = normalize(raw_inputs)
42
+ @inputs = base.class.filters.each_with_object({}) do |(name, filter), inputs|
43
+ inputs[name] = filter.process(@normalized_inputs[name], base)
44
+
45
+ yield name, inputs[name] if block_given?
54
46
  end
47
+ end
55
48
 
56
- private
49
+ # @private
50
+ def normalized
51
+ @normalized_inputs
52
+ end
57
53
 
58
- def normalize_inputs!(inputs)
59
- return inputs if inputs.is_a?(Hash) || inputs.is_a?(Inputs)
54
+ # Turn the inputs into a Hash.
55
+ #
56
+ # @return [Hash]
57
+ def to_h
58
+ @to_h ||= @inputs.transform_values(&:value).freeze
59
+ end
60
60
 
61
- parameters = 'ActionController::Parameters'
62
- klass = parameters.safe_constantize
63
- return inputs.to_unsafe_h if klass && inputs.is_a?(klass)
61
+ def_delegators :to_h,
62
+ :[],
63
+ :dig,
64
+ :each,
65
+ :each_key,
66
+ :each_pair,
67
+ :each_value,
68
+ :empty?,
69
+ :except,
70
+ :fetch,
71
+ :fetch_values,
72
+ :filter,
73
+ :flatten,
74
+ :has_key?,
75
+ :has_value?,
76
+ :include?,
77
+ :inspect,
78
+ :key,
79
+ :key?,
80
+ :keys,
81
+ :length,
82
+ :member?,
83
+ :merge,
84
+ :rassoc,
85
+ :reject,
86
+ :select,
87
+ :size,
88
+ :slice,
89
+ :store,
90
+ :to_a,
91
+ :to_s,
92
+ :value?,
93
+ :values,
94
+ :values_at
64
95
 
65
- raise ArgumentError, "inputs must be a hash or #{parameters}"
66
- end
96
+ # Returns `true` if the given key was in the hash passed to {.run}.
97
+ # Otherwise returns `false`. Use this to figure out if an input was given,
98
+ # even if it was `nil`. Keys within nested hash filter can also be checked
99
+ # by passing them in series. Arrays can be checked in the same manor as
100
+ # hashes by passing an index.
101
+ #
102
+ # @example
103
+ # class Example < ActiveInteraction::Base
104
+ # integer :x, default: nil
105
+ # def execute; given?(:x) end
106
+ # end
107
+ # Example.run!() # => false
108
+ # Example.run!(x: nil) # => true
109
+ # Example.run!(x: rand) # => true
110
+ #
111
+ # @example Nested checks
112
+ # class Example < ActiveInteraction::Base
113
+ # hash :x, default: {} do
114
+ # integer :y, default: nil
115
+ # end
116
+ # array :a, default: [] do
117
+ # integer
118
+ # end
119
+ # def execute; given?(:x, :y) || given?(:a, 2) end
120
+ # end
121
+ # Example.run!() # => false
122
+ # Example.run!(x: nil) # => false
123
+ # Example.run!(x: {}) # => false
124
+ # Example.run!(x: { y: nil }) # => true
125
+ # Example.run!(x: { y: rand }) # => true
126
+ # Example.run!(a: [1, 2]) # => false
127
+ # Example.run!(a: [1, 2, 3]) # => true
128
+ #
129
+ # @param input [#to_sym]
130
+ #
131
+ # @return [Boolean]
132
+ #
133
+ # rubocop:disable all
134
+ def given?(input, *rest)
135
+ filter_level = @base.class
136
+ input_level = @normalized_inputs
67
137
 
68
- def assign_to_grouped_input!(inputs, key, index, value)
69
- key = key.to_sym
138
+ [input, *rest].each do |key_or_index|
139
+ if key_or_index.is_a?(Symbol) || key_or_index.is_a?(String)
140
+ key = key_or_index.to_sym
141
+ key_to_s = key_or_index.to_s
142
+ filter_level = filter_level.filters[key]
70
143
 
71
- inputs[key] = GroupedInput.new unless inputs[key].is_a?(GroupedInput)
72
- inputs[key][index] = value
73
- end
144
+ break false if filter_level.nil? || input_level.nil?
145
+ break false unless input_level.key?(key) || input_level.key?(key_to_s)
146
+
147
+ input_level = input_level[key] || input_level[key_to_s]
148
+ else
149
+ index = key_or_index
150
+ filter_level = filter_level.filters.first.last
151
+
152
+ break false if filter_level.nil? || input_level.nil?
153
+ break false unless index.between?(-input_level.size, input_level.size - 1)
154
+
155
+ input_level = input_level[index]
156
+ end
157
+ end && true
74
158
  end
159
+ # rubocop:enable all
160
+
161
+ private
162
+
163
+ def normalize(inputs)
164
+ convert(inputs)
165
+ .sort
166
+ .each_with_object({}) do |(k, v), h|
167
+ next if self.class.reserved?(k)
168
+
169
+ if (group = GROUPED_INPUT_PATTERN.match(k))
170
+ assign_to_grouped_input!(h, group[:key], group[:index], v)
171
+ else
172
+ h[k.to_sym] = v
173
+ end
174
+ end
175
+ end
176
+
177
+ def convert(inputs)
178
+ return inputs.stringify_keys if inputs.is_a?(Hash)
179
+ return inputs.to_unsafe_h.stringify_keys if inputs.is_a?(ActionController::Parameters)
180
+
181
+ raise ArgumentError, 'inputs must be a hash or ActionController::Parameters'
182
+ end
183
+
184
+ def assign_to_grouped_input!(inputs, key, index, value)
185
+ key = key.to_sym
75
186
 
76
- def initialize(inputs = {})
77
- super(inputs)
187
+ inputs[key] = GroupedInput.new unless inputs[key].is_a?(GroupedInput)
188
+ inputs[key][index] = value
78
189
  end
79
190
  end
80
191
  end
@@ -3,7 +3,6 @@ en:
3
3
  errors:
4
4
  messages:
5
5
  invalid: is invalid
6
- invalid_nested: has an invalid nested value (%{name} => %{value})
7
6
  invalid_type: is not a valid %{type}
8
7
  missing: is required
9
8
  types:
@@ -3,7 +3,6 @@ fr:
3
3
  errors:
4
4
  messages:
5
5
  invalid: est invalide
6
- invalid_nested: contient une valeur imbriquée invalide (%{name} => %{value})
7
6
  invalid_type: a un type invalide (%{type})
8
7
  missing: est obligatoire
9
8
  types:
@@ -3,7 +3,6 @@ it:
3
3
  errors:
4
4
  messages:
5
5
  invalid: non è valido
6
- invalid_nested: ha un valore nidificato non valido (%{name} => %{value})
7
6
  invalid_type: non è di tipo %{type}
8
7
  missing: è obbligatorio
9
8
  types:
@@ -3,7 +3,6 @@ ja:
3
3
  errors:
4
4
  messages:
5
5
  invalid: は無効です
6
- invalid_nested: は無効なネストされた値です (%{name} => %{value})
7
6
  invalid_type: は無効な %{type} です
8
7
  missing: が必要です
9
8
  types:
@@ -3,7 +3,6 @@ pt-BR:
3
3
  errors:
4
4
  messages:
5
5
  invalid: é inválido
6
- invalid_nested: possui um valor aninhado inválido (%{name} => %{value})
7
6
  invalid_type: não é um(a) %{type} válido(a)
8
7
  missing: é obrigatório
9
8
  types:
@@ -8,26 +8,15 @@ module ActiveInteraction
8
8
  class << self
9
9
  # @param context [Base]
10
10
  # @param filters [Hash{Symbol => Filter}]
11
- # @param inputs [Hash{Symbol => Object}]
11
+ # @param inputs [Inputs]
12
12
  def validate(context, filters, inputs)
13
13
  filters.each_with_object([]) do |(name, filter), errors|
14
- filter.clean(inputs[name], context)
15
- rescue NoDefaultError
16
- nil
17
- rescue InvalidNestedValueError => e
18
- errors << [filter.name, :invalid_nested, { name: e.filter_name.inspect, value: e.input_value.inspect }]
19
- rescue InvalidValueError
20
- errors << [filter.name, :invalid_type, { type: type(filter) }]
21
- rescue MissingValueError
22
- errors << [filter.name, :missing]
23
- end
24
- end
14
+ input = filter.process(inputs[name], context)
25
15
 
26
- private
27
-
28
- # @param filter [Filter]
29
- def type(filter)
30
- I18n.translate("#{Base.i18n_scope}.types.#{filter.class.slug}")
16
+ input.errors.each do |error|
17
+ errors << [error.name, error.type, error.options]
18
+ end
19
+ end
31
20
  end
32
21
  end
33
22
  end
@@ -4,5 +4,5 @@ module ActiveInteraction
4
4
  # The version number.
5
5
  #
6
6
  # @return [Gem::Version]
7
- VERSION = Gem::Version.new('4.1.0')
7
+ VERSION = Gem::Version.new('5.0.0')
8
8
  end
@@ -1,7 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'active_model'
4
- require 'active_support/hash_with_indifferent_access'
4
+ require 'active_record'
5
+ require 'active_support/core_ext/hash/indifferent_access'
6
+ require 'action_controller'
5
7
 
6
8
  # Manage application specific business logic.
7
9
  #
@@ -10,41 +12,46 @@ require 'active_support/hash_with_indifferent_access'
10
12
  module ActiveInteraction
11
13
  end
12
14
 
13
- require 'active_interaction/version'
14
- require 'active_interaction/errors'
15
-
16
- require 'active_interaction/concerns/active_modelable'
17
- require 'active_interaction/concerns/active_recordable'
18
- require 'active_interaction/concerns/hashable'
19
- require 'active_interaction/concerns/missable'
20
- require 'active_interaction/concerns/runnable'
21
-
22
- require 'active_interaction/grouped_input'
23
- require 'active_interaction/inputs'
24
-
25
- require 'active_interaction/modules/validation'
26
-
27
- require 'active_interaction/filter_column'
28
- require 'active_interaction/filter'
29
- require 'active_interaction/filters/interface_filter'
30
- require 'active_interaction/filters/abstract_date_time_filter'
31
- require 'active_interaction/filters/abstract_numeric_filter'
32
- require 'active_interaction/filters/array_filter'
33
- require 'active_interaction/filters/boolean_filter'
34
- require 'active_interaction/filters/date_filter'
35
- require 'active_interaction/filters/date_time_filter'
36
- require 'active_interaction/filters/decimal_filter'
37
- require 'active_interaction/filters/file_filter'
38
- require 'active_interaction/filters/float_filter'
39
- require 'active_interaction/filters/hash_filter'
40
- require 'active_interaction/filters/integer_filter'
41
- require 'active_interaction/filters/object_filter'
42
- require 'active_interaction/filters/record_filter'
43
- require 'active_interaction/filters/string_filter'
44
- require 'active_interaction/filters/symbol_filter'
45
- require 'active_interaction/filters/time_filter'
46
-
47
- require 'active_interaction/base'
15
+ require_relative 'active_interaction/version'
16
+ require_relative 'active_interaction/exceptions'
17
+ require_relative 'active_interaction/errors'
18
+
19
+ require_relative 'active_interaction/concerns/active_modelable'
20
+ require_relative 'active_interaction/concerns/active_recordable'
21
+ require_relative 'active_interaction/concerns/hashable'
22
+ require_relative 'active_interaction/concerns/missable'
23
+ require_relative 'active_interaction/concerns/runnable'
24
+
25
+ require_relative 'active_interaction/grouped_input'
26
+ require_relative 'active_interaction/input'
27
+ require_relative 'active_interaction/array_input'
28
+ require_relative 'active_interaction/hash_input'
29
+ require_relative 'active_interaction/inputs'
30
+
31
+ require_relative 'active_interaction/modules/validation'
32
+
33
+ require_relative 'active_interaction/filter/column'
34
+ require_relative 'active_interaction/filter/error'
35
+ require_relative 'active_interaction/filter'
36
+ require_relative 'active_interaction/filters/interface_filter'
37
+ require_relative 'active_interaction/filters/abstract_date_time_filter'
38
+ require_relative 'active_interaction/filters/abstract_numeric_filter'
39
+ require_relative 'active_interaction/filters/array_filter'
40
+ require_relative 'active_interaction/filters/boolean_filter'
41
+ require_relative 'active_interaction/filters/date_filter'
42
+ require_relative 'active_interaction/filters/date_time_filter'
43
+ require_relative 'active_interaction/filters/decimal_filter'
44
+ require_relative 'active_interaction/filters/file_filter'
45
+ require_relative 'active_interaction/filters/float_filter'
46
+ require_relative 'active_interaction/filters/hash_filter'
47
+ require_relative 'active_interaction/filters/integer_filter'
48
+ require_relative 'active_interaction/filters/object_filter'
49
+ require_relative 'active_interaction/filters/record_filter'
50
+ require_relative 'active_interaction/filters/string_filter'
51
+ require_relative 'active_interaction/filters/symbol_filter'
52
+ require_relative 'active_interaction/filters/time_filter'
53
+
54
+ require_relative 'active_interaction/base'
48
55
 
49
56
  I18n.load_path.unshift(
50
57
  *Dir.glob(