active_interaction 3.8.3 → 4.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +157 -0
- data/README.md +93 -107
- data/lib/active_interaction.rb +1 -7
- data/lib/active_interaction/base.rb +23 -26
- data/lib/active_interaction/concerns/active_modelable.rb +1 -3
- data/lib/active_interaction/concerns/active_recordable.rb +1 -6
- data/lib/active_interaction/concerns/hashable.rb +0 -1
- data/lib/active_interaction/concerns/missable.rb +0 -1
- data/lib/active_interaction/concerns/runnable.rb +6 -12
- data/lib/active_interaction/errors.rb +3 -6
- data/lib/active_interaction/filter.rb +51 -37
- data/lib/active_interaction/filter_column.rb +0 -3
- data/lib/active_interaction/filters/abstract_date_time_filter.rb +34 -36
- data/lib/active_interaction/filters/abstract_numeric_filter.rb +27 -17
- data/lib/active_interaction/filters/array_filter.rb +57 -36
- data/lib/active_interaction/filters/boolean_filter.rb +26 -12
- data/lib/active_interaction/filters/date_filter.rb +1 -2
- data/lib/active_interaction/filters/date_time_filter.rb +1 -2
- data/lib/active_interaction/filters/decimal_filter.rb +10 -28
- data/lib/active_interaction/filters/file_filter.rb +6 -5
- data/lib/active_interaction/filters/float_filter.rb +1 -2
- data/lib/active_interaction/filters/hash_filter.rb +37 -27
- data/lib/active_interaction/filters/integer_filter.rb +7 -8
- data/lib/active_interaction/filters/interface_filter.rb +48 -14
- data/lib/active_interaction/filters/object_filter.rb +23 -50
- data/lib/active_interaction/filters/record_filter.rb +10 -35
- data/lib/active_interaction/filters/string_filter.rb +21 -12
- data/lib/active_interaction/filters/symbol_filter.rb +13 -7
- data/lib/active_interaction/filters/time_filter.rb +19 -22
- data/lib/active_interaction/grouped_input.rb +0 -3
- data/lib/active_interaction/inputs.rb +89 -0
- data/lib/active_interaction/modules/input_processor.rb +1 -4
- data/lib/active_interaction/modules/validation.rb +9 -12
- data/lib/active_interaction/version.rb +1 -3
- data/spec/active_interaction/base_spec.rb +13 -41
- data/spec/active_interaction/concerns/active_modelable_spec.rb +0 -2
- data/spec/active_interaction/concerns/active_recordable_spec.rb +0 -2
- data/spec/active_interaction/concerns/hashable_spec.rb +1 -3
- data/spec/active_interaction/concerns/missable_spec.rb +0 -2
- data/spec/active_interaction/concerns/runnable_spec.rb +9 -13
- data/spec/active_interaction/errors_spec.rb +4 -25
- data/spec/active_interaction/filter_column_spec.rb +0 -2
- data/spec/active_interaction/filter_spec.rb +0 -2
- data/spec/active_interaction/filters/abstract_date_time_filter_spec.rb +1 -3
- data/spec/active_interaction/filters/abstract_numeric_filter_spec.rb +1 -3
- data/spec/active_interaction/filters/array_filter_spec.rb +41 -15
- data/spec/active_interaction/filters/boolean_filter_spec.rb +58 -4
- data/spec/active_interaction/filters/date_filter_spec.rb +43 -3
- data/spec/active_interaction/filters/date_time_filter_spec.rb +43 -3
- data/spec/active_interaction/filters/decimal_filter_spec.rb +57 -3
- data/spec/active_interaction/filters/file_filter_spec.rb +1 -3
- data/spec/active_interaction/filters/float_filter_spec.rb +60 -4
- data/spec/active_interaction/filters/hash_filter_spec.rb +19 -9
- data/spec/active_interaction/filters/integer_filter_spec.rb +49 -7
- data/spec/active_interaction/filters/interface_filter_spec.rb +397 -24
- data/spec/active_interaction/filters/object_filter_spec.rb +23 -59
- data/spec/active_interaction/filters/record_filter_spec.rb +23 -49
- data/spec/active_interaction/filters/string_filter_spec.rb +15 -3
- data/spec/active_interaction/filters/symbol_filter_spec.rb +15 -3
- data/spec/active_interaction/filters/time_filter_spec.rb +65 -3
- data/spec/active_interaction/grouped_input_spec.rb +0 -2
- data/spec/active_interaction/i18n_spec.rb +3 -7
- data/spec/active_interaction/{modules/input_processor_spec.rb → inputs_spec.rb} +3 -5
- data/spec/active_interaction/integration/array_interaction_spec.rb +18 -22
- data/spec/active_interaction/integration/boolean_interaction_spec.rb +0 -2
- data/spec/active_interaction/integration/date_interaction_spec.rb +0 -2
- data/spec/active_interaction/integration/date_time_interaction_spec.rb +0 -2
- data/spec/active_interaction/integration/file_interaction_spec.rb +0 -2
- data/spec/active_interaction/integration/float_interaction_spec.rb +0 -2
- data/spec/active_interaction/integration/hash_interaction_spec.rb +0 -2
- data/spec/active_interaction/integration/integer_interaction_spec.rb +0 -2
- data/spec/active_interaction/integration/interface_interaction_spec.rb +1 -3
- data/spec/active_interaction/integration/object_interaction_spec.rb +0 -2
- data/spec/active_interaction/integration/string_interaction_spec.rb +0 -2
- data/spec/active_interaction/integration/symbol_interaction_spec.rb +0 -2
- data/spec/active_interaction/integration/time_interaction_spec.rb +14 -18
- data/spec/active_interaction/modules/validation_spec.rb +1 -3
- data/spec/spec_helper.rb +2 -6
- data/spec/support/concerns.rb +0 -2
- data/spec/support/filters.rb +13 -9
- data/spec/support/interactions.rb +22 -14
- metadata +77 -52
- data/lib/active_interaction/backports.rb +0 -59
- data/lib/active_interaction/filters/abstract_filter.rb +0 -19
- data/spec/active_interaction/filters/abstract_filter_spec.rb +0 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: acc5f59cdd588429a58556cea7b70aa0c43a6a13c523a682cac266cfc7ab76a1
|
4
|
+
data.tar.gz: 9a58db1735b436ae91a70baf9c2eab9ef4851a20a9e51c05c6f243af6e3c282b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c78b1f82d8593a238a2076f7351146e51079d163d963cc830d9e086bbc82bd791fbc95527d4fc829e3c38039bb77ce06fefe82520f5b6f2148a64384a8e3a339
|
7
|
+
data.tar.gz: 362a8b86512c8ef05d9582a377000e06e2b8b0855c112458020911fa77477c3c98cd10555e81d259cfc767f79c1eb8b03e9ec12124cfca38c552208006e1a70a
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,157 @@
|
|
1
|
+
# [4.0.0][] (2021-01-10)
|
2
|
+
|
3
|
+
## Changed
|
4
|
+
|
5
|
+
- drop support for Ruby < 2.5, added support for Ruby 3.0
|
6
|
+
- drop support for Rails < 5.0, added support for Rails 6.1
|
7
|
+
- [#398][] - Predicate methods have been removed.
|
8
|
+
([how to upgrade](#predicate-methods))
|
9
|
+
- [#412][] - Filters will now treat blank string values as `nil`
|
10
|
+
(except `string` and `symbol`). ([how to upgrade](#blank-values-treated-as-nil-for-filters))
|
11
|
+
- [#392][] - Integer parsing now defaults the base to 10.
|
12
|
+
([how to upgrade](#integer-parsing-base-now-10))
|
13
|
+
- The `inputs` method now returns an `ActiveInteraction::Input` instead of a
|
14
|
+
hash. The `ActiveInteraction::Input` class still responds to all hash methods.
|
15
|
+
- The `object` and `record` filters now only accept an instance of the correct
|
16
|
+
class type or a subclass of the correct class. They no longer allow you to
|
17
|
+
check for included modules. ([how to upgrade](#object-and-record-filter-changes))
|
18
|
+
- The `interface` filter will now look for an ancestor of the value passed
|
19
|
+
based on the name of the interface or the value passed in the `from` option.
|
20
|
+
- The `InvalidClassError` has been replaced by `InvalidNameError`.
|
21
|
+
- When introspecting an array filter, the inner filter is referenced by :'0'
|
22
|
+
instead of the singularized version of the array filter name.
|
23
|
+
|
24
|
+
## Added
|
25
|
+
|
26
|
+
- Implicit coercion of types are now supported in filters (e.g. to_str, to_int,
|
27
|
+
etc).
|
28
|
+
- The `interface` and `record` filters, when used as an inner filter for an
|
29
|
+
`array`, will have their `from/class` option set to a singularized version of
|
30
|
+
the `array` filter name.
|
31
|
+
|
32
|
+
## Upgrading
|
33
|
+
|
34
|
+
### Predicate Methods
|
35
|
+
|
36
|
+
We've removed the predicate methods that were automatically generated for each
|
37
|
+
input. They would return true if an input was not `nil`. They can be manually
|
38
|
+
replaced with that same check.
|
39
|
+
|
40
|
+
```ruby
|
41
|
+
# v3.8
|
42
|
+
class Example < ActiveInteraction::Base
|
43
|
+
string :first_name
|
44
|
+
|
45
|
+
validates :first_name,
|
46
|
+
presence: true,
|
47
|
+
if: :first_name?
|
48
|
+
|
49
|
+
def execute
|
50
|
+
# ...
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
# v4.0
|
55
|
+
class Example < ActiveInteraction::Base
|
56
|
+
string :first_name
|
57
|
+
|
58
|
+
validates :first_name,
|
59
|
+
presence: true,
|
60
|
+
unless: 'first_name.nil?'
|
61
|
+
|
62
|
+
def execute
|
63
|
+
# ...
|
64
|
+
end
|
65
|
+
end
|
66
|
+
```
|
67
|
+
|
68
|
+
## Blank Values Treated As `nil` For Filters
|
69
|
+
|
70
|
+
In an effort to improve form support, strings that are `blank?` will
|
71
|
+
be converted into `nil` for all filters except `string` and `symbol`.
|
72
|
+
Previously, blank strings would have cased `:invalid_type` errors but
|
73
|
+
they'll now cause a `:missing` error which should be more form
|
74
|
+
friendly. If the filter has a default, the blank string will cause
|
75
|
+
the default to be used.
|
76
|
+
|
77
|
+
```ruby
|
78
|
+
class Example < ActiveInteraction::Base
|
79
|
+
integer :i
|
80
|
+
boolean :b, default: false
|
81
|
+
|
82
|
+
def execute
|
83
|
+
[i, b]
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
# v3.8
|
88
|
+
Example.run(i: '', b: '').errors.details
|
89
|
+
=> {:i=>[{:error=>:invalid_type, :type=>"integer"}], :b=>[{:error=>:invalid_type, :type=>"boolean"}]}
|
90
|
+
|
91
|
+
# v4.0
|
92
|
+
Example.run(i: '', b: '').errors.details
|
93
|
+
=> {:i=>[{:error=>:missing}]}
|
94
|
+
|
95
|
+
# v3.8
|
96
|
+
Example.run(i: 0, b: '').errors.details
|
97
|
+
=> {:b=>[{:error=>:invalid_type, :type=>"boolean"}]}
|
98
|
+
|
99
|
+
# v4.0
|
100
|
+
Example.run(i: 0, b: '').errors.details
|
101
|
+
=> {}
|
102
|
+
|
103
|
+
Example.run(i: 0, b: '').result
|
104
|
+
=> [0, false] # the default is used for `:b`
|
105
|
+
```
|
106
|
+
|
107
|
+
### Integer Parsing Base Now 10
|
108
|
+
|
109
|
+
Integers are parsed using `Integer`. By default this meant that when
|
110
|
+
strings were parsed, radix indicators (0, 0b, and 0x) were honored. Now
|
111
|
+
we're defaulting the base to `10`. This means all strings will be parsed
|
112
|
+
as though they are base 10.
|
113
|
+
|
114
|
+
```ruby
|
115
|
+
class Example < ActiveInteraction::Base
|
116
|
+
integer :x
|
117
|
+
|
118
|
+
def execute
|
119
|
+
x
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
# v3.8
|
124
|
+
Example.run!(x: '010')
|
125
|
+
# => 8
|
126
|
+
|
127
|
+
# v4.0
|
128
|
+
Example.run!(x: '010')
|
129
|
+
# => 10
|
130
|
+
```
|
131
|
+
|
132
|
+
If you want the old behavior that respected the radix you can pass `0`
|
133
|
+
as the base.
|
134
|
+
|
135
|
+
```diff
|
136
|
+
- integer :x
|
137
|
+
+ integer :x, base: 0
|
138
|
+
```
|
139
|
+
|
140
|
+
With that change, we can see the radix is respected again.
|
141
|
+
|
142
|
+
```ruby
|
143
|
+
# v4.0.0
|
144
|
+
Example.run!(x: '010')
|
145
|
+
# => 8
|
146
|
+
```
|
147
|
+
|
148
|
+
### Object and Record Filter Changes
|
149
|
+
|
150
|
+
The `object` and `record` filters used to be able to check for included modules
|
151
|
+
in addition to a class type. This has been removed. If you want any object that
|
152
|
+
has a particular module included, you'll need to use the newly expanded
|
153
|
+
`interface` filter.
|
154
|
+
|
1
155
|
# [3.8.3][] (2020-04-22)
|
2
156
|
|
3
157
|
## Fixed
|
@@ -777,6 +931,7 @@ Example.run
|
|
777
931
|
|
778
932
|
- Initial release.
|
779
933
|
|
934
|
+
[4.0.0]: https://github.com/AaronLasseigne/active_interaction/compare/v3.8.3...v4.0.0
|
780
935
|
[3.8.3]: https://github.com/AaronLasseigne/active_interaction/compare/v3.8.2...v3.8.3
|
781
936
|
[3.8.2]: https://github.com/AaronLasseigne/active_interaction/compare/v3.8.1...v3.8.2
|
782
937
|
[3.8.1]: https://github.com/AaronLasseigne/active_interaction/compare/v3.8.0...v3.8.1
|
@@ -979,3 +1134,5 @@ Example.run
|
|
979
1134
|
[#476]: https://github.com/AaronLasseigne/active_interaction/issues/476
|
980
1135
|
[#479]: https://github.com/AaronLasseigne/active_interaction/issues/479
|
981
1136
|
[#486]: https://github.com/AaronLasseigne/active_interaction/issues/486
|
1137
|
+
[#392]: https://github.com/AaronLasseigne/active_interaction/issues/392
|
1138
|
+
[#398]: https://github.com/AaronLasseigne/active_interaction/issues/398
|
data/README.md
CHANGED
@@ -4,7 +4,7 @@ ActiveInteraction manages application-specific business logic.
|
|
4
4
|
It's an implementation of the command pattern in Ruby.
|
5
5
|
|
6
6
|
[![Version](https://img.shields.io/gem/v/active_interaction.svg?style=flat-square)](https://rubygems.org/gems/active_interaction)
|
7
|
-
[![
|
7
|
+
[![Test](https://img.shields.io/github/workflow/status/AaronLasseigne/active_interaction/Test?label=Test&style=flat-square)](https://github.com/AaronLasseigne/active_interaction/actions?query=workflow%3ATest)
|
8
8
|
[![Coverage](https://img.shields.io/coveralls/github/AaronLasseigne/active_interaction.svg?style=flat-square)](https://coveralls.io/r/orgsync/active_interaction)
|
9
9
|
[![Climate](https://img.shields.io/codeclimate/maintainability/orgsync/active_interaction.svg?style=flat-square)](https://codeclimate.com/github/orgsync/active_interaction)
|
10
10
|
|
@@ -55,7 +55,6 @@ handles your verbs.
|
|
55
55
|
- [Forms](#forms)
|
56
56
|
- [Grouped inputs](#grouped-inputs)
|
57
57
|
- [Optional inputs](#optional-inputs)
|
58
|
-
- [Predicates](#predicates)
|
59
58
|
- [Translations](#translations)
|
60
59
|
- [Credits](#credits)
|
61
60
|
|
@@ -66,23 +65,19 @@ handles your verbs.
|
|
66
65
|
Add it to your Gemfile:
|
67
66
|
|
68
67
|
``` rb
|
69
|
-
gem 'active_interaction', '~>
|
68
|
+
gem 'active_interaction', '~> 4.0'
|
70
69
|
```
|
71
70
|
|
72
71
|
Or install it manually:
|
73
72
|
|
74
73
|
``` sh
|
75
|
-
$ gem install active_interaction --version '~>
|
74
|
+
$ gem install active_interaction --version '~> 4.0'
|
76
75
|
```
|
77
76
|
|
78
77
|
This project uses [Semantic Versioning][]. Check out [GitHub releases][] for a
|
79
78
|
detailed list of changes. For help upgrading to version 2, please read [the
|
80
79
|
announcement post][].
|
81
80
|
|
82
|
-
ActiveInteraction works with Ruby 2.0 through 2.6 and ActiveModel 4.0 through
|
83
|
-
6.0. If you want to use ActiveInteraction with an older version of Ruby or
|
84
|
-
ActiveModel, use ActiveInteraction < 3.0.0.
|
85
|
-
|
86
81
|
## Basic usage
|
87
82
|
|
88
83
|
To define an interaction, create a subclass of `ActiveInteraction::Base`. Then
|
@@ -241,7 +236,8 @@ ArrayInteraction.run!(toppings: [:cheese, 'pepperoni'])
|
|
241
236
|
# => 2
|
242
237
|
```
|
243
238
|
|
244
|
-
Use a block to constrain the types of elements an array can contain.
|
239
|
+
Use a block to constrain the types of elements an array can contain. Note that
|
240
|
+
you can only have one filter inside an array block, and it must not have a name.
|
245
241
|
|
246
242
|
``` rb
|
247
243
|
array :birthdays do
|
@@ -249,19 +245,29 @@ array :birthdays do
|
|
249
245
|
end
|
250
246
|
```
|
251
247
|
|
252
|
-
|
253
|
-
|
248
|
+
For `interface`, `object`, and `record` filters, the name of the array filter
|
249
|
+
will be singularized and used to determine the type of value passed. In the
|
250
|
+
example below, the objects passed would need to be of type `Cow`.
|
254
251
|
|
255
252
|
``` rb
|
256
253
|
array :cows do
|
257
|
-
object
|
254
|
+
object
|
255
|
+
end
|
256
|
+
```
|
257
|
+
|
258
|
+
You can override this by passing the necessary information to the inner filter.
|
259
|
+
|
260
|
+
```ruby
|
261
|
+
array :managers do
|
262
|
+
object class: People
|
258
263
|
end
|
259
264
|
```
|
260
265
|
|
261
266
|
### Boolean
|
262
267
|
|
263
|
-
Boolean filters convert the strings `"1"` and `"
|
264
|
-
`true`. They also convert `"0"` and `"
|
268
|
+
Boolean filters convert the strings `"1"`, `"true"`, and `"on"`
|
269
|
+
(case-insensitive) into `true`. They also convert `"0"`, `"false"`, and `"off"`
|
270
|
+
into `false`. Blank strings will be treated as `nil`.
|
265
271
|
|
266
272
|
``` rb
|
267
273
|
class BooleanInteraction < ActiveInteraction::Base
|
@@ -353,8 +359,45 @@ hash :stuff,
|
|
353
359
|
|
354
360
|
### Interface
|
355
361
|
|
356
|
-
Interface filters allow you to specify
|
357
|
-
|
362
|
+
Interface filters allow you to specify an interface that the passed value must
|
363
|
+
meet in order to pass. The name of the interface is used to look for a constant
|
364
|
+
inside the ancestor listing for the passed value. This allows for a variety of
|
365
|
+
checks depending on what's passed. Class instances are checked for an included
|
366
|
+
module or an inherited ancestor class. Classes are checked for an extended
|
367
|
+
module or an inherited ancestor class. Modules are checked for an extended
|
368
|
+
module.
|
369
|
+
|
370
|
+
``` rb
|
371
|
+
class InterfaceInteraction < ActiveInteraction::Base
|
372
|
+
interface :exception
|
373
|
+
|
374
|
+
def execute
|
375
|
+
exception
|
376
|
+
end
|
377
|
+
end
|
378
|
+
|
379
|
+
InterfaceInteraction.run!(exception: Exception)
|
380
|
+
# ActiveInteraction::InvalidInteractionError: Exception is not a valid interface
|
381
|
+
InterfaceInteraction.run!(exception: NameError) # a subclass of Exception
|
382
|
+
# => NameError
|
383
|
+
```
|
384
|
+
|
385
|
+
You can use `:from` to specify a class or module. This would be the equivalent
|
386
|
+
of what's above.
|
387
|
+
|
388
|
+
```rb
|
389
|
+
class InterfaceInteraction < ActiveInteraction::Base
|
390
|
+
interface :error,
|
391
|
+
from: Exception
|
392
|
+
|
393
|
+
def execute
|
394
|
+
error
|
395
|
+
end
|
396
|
+
end
|
397
|
+
```
|
398
|
+
|
399
|
+
You can also create an anonymous interface on the fly by passing the `methods`
|
400
|
+
option.
|
358
401
|
|
359
402
|
``` rb
|
360
403
|
class InterfaceInteraction < ActiveInteraction::Base
|
@@ -378,30 +421,10 @@ InterfaceInteraction.run!(serializer: JSON)
|
|
378
421
|
# => "{\"is_json\":true}"
|
379
422
|
```
|
380
423
|
|
381
|
-
NOTE: The `methods` option is optional.
|
382
|
-
|
383
|
-
```rb
|
384
|
-
class InterfaceInteraction < ActiveInteraction::Base
|
385
|
-
interface :anything
|
386
|
-
|
387
|
-
def execute
|
388
|
-
anything.class
|
389
|
-
end
|
390
|
-
end
|
391
|
-
|
392
|
-
require 'json'
|
393
|
-
|
394
|
-
InterfaceInteraction.run!(anything: Hash.new)
|
395
|
-
# => Hash
|
396
|
-
InterfaceInteraction.run!
|
397
|
-
# => NilClass
|
398
|
-
```
|
399
|
-
|
400
424
|
### Object
|
401
425
|
|
402
|
-
Object filters allow you to require an instance of a particular class
|
403
|
-
|
404
|
-
it also works with classes that have mixed modules in with `include`.
|
426
|
+
Object filters allow you to require an instance of a particular class or one of
|
427
|
+
its subclasses.
|
405
428
|
|
406
429
|
``` rb
|
407
430
|
class Cow
|
@@ -438,8 +461,8 @@ object :dolly3,
|
|
438
461
|
```
|
439
462
|
|
440
463
|
If you have value objects or you would like to build one object from another,
|
441
|
-
you can use the `converter` option. It is only called if the value provided
|
442
|
-
not
|
464
|
+
you can use the `converter` option. It is only called if the value provided is
|
465
|
+
not an instance of the class or one of its subclasses. The `converter` option
|
443
466
|
accepts a symbol that specifies a class method on the object class or a proc.
|
444
467
|
Both will be passed the value and any errors thrown inside the converter will
|
445
468
|
cause the value to be considered invalid. Any returned value that is not the
|
@@ -466,13 +489,13 @@ ObjectInteraction.run!(ip_address: 1)
|
|
466
489
|
|
467
490
|
### Record
|
468
491
|
|
469
|
-
Record filters allow you to require an instance of a particular class or
|
470
|
-
that can be used to locate an instance of the
|
471
|
-
|
472
|
-
|
473
|
-
|
474
|
-
|
475
|
-
|
492
|
+
Record filters allow you to require an instance of a particular class (or one
|
493
|
+
of its subclasses) or a value that can be used to locate an instance of the
|
494
|
+
object. If the value does not match, it will call `find` on the class of the
|
495
|
+
record. This is particularly useful when working with ActiveRecord objects.
|
496
|
+
Like an object filter, the class is derived from the name passed but can be
|
497
|
+
specified with the `class` option. The value given to the `default` option will
|
498
|
+
also be found.
|
476
499
|
|
477
500
|
``` rb
|
478
501
|
class RecordInteraction < ActiveInteraction::Base
|
@@ -542,9 +565,10 @@ SymbolInteraction.run!(method: :object_id)
|
|
542
565
|
### Dates and times
|
543
566
|
|
544
567
|
Filters that work with dates and times behave similarly. By default, they all
|
545
|
-
convert strings into their expected data types using `.parse`.
|
546
|
-
`format` option, they will instead
|
547
|
-
formats won't work with `DateTime`
|
568
|
+
convert strings into their expected data types using `.parse`. Blank strings
|
569
|
+
will be treated as `nil`. If you give the `format` option, they will instead
|
570
|
+
convert strings using `.strptime`. Note that formats won't work with `DateTime`
|
571
|
+
and `Time` filters if a time zone is set.
|
548
572
|
|
549
573
|
#### Date
|
550
574
|
|
@@ -618,7 +642,8 @@ time :start,
|
|
618
642
|
### Numbers
|
619
643
|
|
620
644
|
All numeric filters accept numeric input. They will also convert strings using
|
621
|
-
the appropriate method from `Kernel` (like `.Float`).
|
645
|
+
the appropriate method from `Kernel` (like `.Float`). Blank strings will be
|
646
|
+
treated as `nil`.
|
622
647
|
|
623
648
|
#### Decimal
|
624
649
|
|
@@ -679,24 +704,27 @@ IntegerInteraction.run!(limit: 10)
|
|
679
704
|
```
|
680
705
|
|
681
706
|
When a `String` is passed into an `integer` input, the value will be coerced.
|
682
|
-
|
683
|
-
|
684
|
-
|
707
|
+
A default base of `10` is used though it may be overridden with the `base` option.
|
708
|
+
If a base of `0` is provided, the coercion will respect radix indicators present
|
709
|
+
in the string.
|
685
710
|
|
686
711
|
``` rb
|
687
712
|
class IntegerInteraction < ActiveInteraction::Base
|
688
|
-
integer :limit1
|
689
|
-
integer :limit2
|
713
|
+
integer :limit1
|
714
|
+
integer :limit2, base: 8
|
715
|
+
integer :limit3, base: 0
|
690
716
|
|
691
717
|
def execute
|
692
|
-
[limit1, limit2]
|
718
|
+
[limit1, limit2, limit3]
|
693
719
|
end
|
694
720
|
end
|
695
721
|
|
696
|
-
IntegerInteraction.run!(limit1:
|
697
|
-
# => [
|
698
|
-
IntegerInteraction.run!(limit1: "
|
699
|
-
#
|
722
|
+
IntegerInteraction.run!(limit1: 71, limit2: 71, limit3: 71)
|
723
|
+
# => [71, 71, 71]
|
724
|
+
IntegerInteraction.run!(limit1: "071", limit2: "071", limit3: "0x71")
|
725
|
+
# => [71, 57, 113]
|
726
|
+
IntegerInteraction.run!(limit1: "08", limit2: "08", limit3: "08")
|
727
|
+
ActiveInteraction::InvalidInteractionError: Limit2 is not a valid integer, Limit3 is not a valid integer
|
700
728
|
```
|
701
729
|
|
702
730
|
## Rails
|
@@ -940,10 +968,6 @@ The interaction that updates accounts is more complicated than the others. It
|
|
940
968
|
requires an account to update, but the other inputs are optional. If they're
|
941
969
|
missing, it'll ignore those attributes. If they're present, it'll update them.
|
942
970
|
|
943
|
-
ActiveInteraction generates predicate methods (like `#first_name?`) for your
|
944
|
-
inputs. They will return `false` if the input is `nil` and `true` otherwise.
|
945
|
-
Skip to [the predicates section](#predicates) for more information about them.
|
946
|
-
|
947
971
|
``` rb
|
948
972
|
class UpdateAccount < ActiveInteraction::Base
|
949
973
|
object :account
|
@@ -953,14 +977,14 @@ class UpdateAccount < ActiveInteraction::Base
|
|
953
977
|
|
954
978
|
validates :first_name,
|
955
979
|
presence: true,
|
956
|
-
|
980
|
+
unless: 'first_name.nil?'
|
957
981
|
validates :last_name,
|
958
982
|
presence: true,
|
959
|
-
|
983
|
+
unless: 'last_name.nil?'
|
960
984
|
|
961
985
|
def execute
|
962
|
-
account.first_name = first_name if first_name?
|
963
|
-
account.last_name = last_name if last_name?
|
986
|
+
account.first_name = first_name if first_name.present?
|
987
|
+
account.last_name = last_name if last_name.present?
|
964
988
|
|
965
989
|
unless account.save
|
966
990
|
errors.merge!(account.errors)
|
@@ -1177,9 +1201,6 @@ def execute
|
|
1177
1201
|
end
|
1178
1202
|
```
|
1179
1203
|
|
1180
|
-
These types of errors will become standard with Rails 5. ActiveInteraction's
|
1181
|
-
implementation is based off of [active_model-errors_details][].
|
1182
|
-
|
1183
1204
|
ActiveInteraction also supports merging errors. This is useful if you want to
|
1184
1205
|
delegate validation to some other object. For example, if you have an
|
1185
1206
|
interaction that updates a record, you might want that record to validate
|
@@ -1375,41 +1396,6 @@ UpdateUser.run!(user: user, birthday: nil)
|
|
1375
1396
|
UpdateUser.run!(user: user, birthday: Date.new(2000, 1, 2))
|
1376
1397
|
```
|
1377
1398
|
|
1378
|
-
### Predicates
|
1379
|
-
|
1380
|
-
ActiveInteraction creates a predicate method for every input defined by a
|
1381
|
-
filter. So if you have an input called `foo`, there will be a predicate method
|
1382
|
-
called `#foo?`. That method will tell you if the input was given (that is, if
|
1383
|
-
it was not `nil`).
|
1384
|
-
|
1385
|
-
``` rb
|
1386
|
-
class SayHello < ActiveInteraction::Base
|
1387
|
-
string :name,
|
1388
|
-
default: nil
|
1389
|
-
|
1390
|
-
def execute
|
1391
|
-
if name?
|
1392
|
-
"Hello, #{name}!"
|
1393
|
-
else
|
1394
|
-
"Howdy, stranger!"
|
1395
|
-
end
|
1396
|
-
end
|
1397
|
-
end
|
1398
|
-
|
1399
|
-
SayHello.run!(name: nil)
|
1400
|
-
# => "Howdy, stranger!"
|
1401
|
-
SayHello.run!(name: 'Taylor')
|
1402
|
-
# => "Hello, Taylor!"
|
1403
|
-
```
|
1404
|
-
|
1405
|
-
This can be confusing for boolean inputs. If you have some boolean input `foo`,
|
1406
|
-
then the actual value of that input is available through `foo`. The associated
|
1407
|
-
predicate method, `#foo?`, will tell you if that value is not `nil`. So it will
|
1408
|
-
only be `false` if the input is optional and happens to be `nil`.
|
1409
|
-
|
1410
|
-
See [the optional inputs section][] for help on determining if an input was
|
1411
|
-
present in the input hash instead of just `nil`.
|
1412
|
-
|
1413
1399
|
### Translations
|
1414
1400
|
|
1415
1401
|
ActiveInteraction is i18n aware out of the box! All you have to do is add
|