Releases: AaronLasseigne/active_interaction
v4.0.2
v4.0.1
v4.0.0
Changed
- drop support for Ruby < 2.5, added support for Ruby 3.0
- drop support for Rails < 5.0, added support for Rails 6.1
- #398 - Predicate methods have been removed.
- #412 - Filters will now treat blank string values as
nil
(exceptstring
andsymbol
). - #392 - Integer parsing now defaults the base to 10.
- The
inputs
method now returns anActiveInteraction::Input
instead of a
hash. TheActiveInteraction::Input
class still responds to all hash methods. - The
object
andrecord
filters now only accept an instance of the correct
class type or a subclass of the correct class. They no longer allow you to
check for included modules. - The
interface
filter will now look for an ancestor of the value passed
based on the name of the interface or the value passed in thefrom
option. - The
InvalidClassError
has been replaced byInvalidNameError
. - When introspecting an array filter, the inner filter is referenced by :'0'
instead of the singularized version of the array filter name.
Added
- Implicit coercion of types are now supported in filters (e.g. to_str, to_int,
etc). - The
interface
andrecord
filters, when used as an inner filter for an
array
, will have theirfrom/class
option set to a singularized version of
thearray
filter name.
Upgrading
Predicate Methods
We've removed the predicate methods that were automatically generated for each
input. They would return true if an input was not nil
. They can be manually
replaced with that same check.
# v3.8
class Example < ActiveInteraction::Base
string :first_name
validates :first_name,
presence: true,
if: :first_name?
def execute
# ...
end
end
# v4.0
class Example < ActiveInteraction::Base
string :first_name
validates :first_name,
presence: true,
unless: 'first_name.nil?'
def execute
# ...
end
end
Blank Values Treated As nil
For Filters
In an effort to improve form support, strings that are blank?
will
be converted into nil
for all filters except string
and symbol
.
Previously, blank strings would have cased :invalid_type
errors but
they'll now cause a :missing
error which should be more form
friendly. If the filter has a default, the blank string will cause
the default to be used.
class Example < ActiveInteraction::Base
integer :i
boolean :b, default: false
def execute
[i, b]
end
end
# v3.8
Example.run(i: '', b: '').errors.details
=> {:i=>[{:error=>:invalid_type, :type=>"integer"}], :b=>[{:error=>:invalid_type, :type=>"boolean"}]}
# v4.0
Example.run(i: '', b: '').errors.details
=> {:i=>[{:error=>:missing}]}
# v3.8
Example.run(i: 0, b: '').errors.details
=> {:b=>[{:error=>:invalid_type, :type=>"boolean"}]}
# v4.0
Example.run(i: 0, b: '').errors.details
=> {}
Example.run(i: 0, b: '').result
=> [0, false] # the default is used for `:b`
Integer Parsing Base Now 10
Integers are parsed using Integer
. By default this meant that when
strings were parsed, radix indicators (0, 0b, and 0x) were honored. Now
we're defaulting the base to 10
. This means all strings will be parsed
as though they are base 10.
class Example < ActiveInteraction::Base
integer :x
def execute
x
end
end
# v3.8
Example.run!(x: '010')
# => 8
# v4.0
Example.run!(x: '010')
# => 10
If you want the old behavior that respected the radix you can pass 0
as the base.
- integer :x
+ integer :x, base: 0
With that change, we can see the radix is respected again.
# v4.0.0
Example.run!(x: '010')
# => 8
Object and Record Filter Changes
The object
and record
filters used to be able to check for included modules
in addition to a class type. This has been removed. If you want any object that
has a particular module included, you'll need to use the newly expanded
interface
filter.
v3.8.3
v3.8.2
v3.8.1
Fixed
- The implementation for providing a failing interaction on
InvalidInteractionError
was a breaking API change. It now works without breaking the API.