4.0.0 (2021-01-10)
- 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. (how to upgrade)
- [#412][] - Filters will now treat blank string values as
nil
(exceptstring
andsymbol
). (how to upgrade) - #392 - Integer parsing now defaults the base to 10. (how to upgrade)
- 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. (how to upgrade) - 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.
- 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 anarray
, will have theirfrom/class
option set to a singularized version of thearray
filter name.
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
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`
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
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.
3.8.3 (2020-04-22)
- [486][]
valid?
returns true if block not called and error added in execute around callback.
3.8.2 (2020-04-22)
- [479][] Composed interactions that throw errors now show a complete backtrace instead of ending at the
run!
of the outermost interaction.
3.8.1 (2020-04-04)
- The implementation for providing a failing interaction on
InvalidInteractionError
was a breaking API change. It now works without breaking the API.
3.8.0 (2020-02-28)
- #477
InvalidInteractionError
now provides access to the failing interaction by callinginteraction
. - #476 Update
given?
to check for items in an array by passing an index.
3.7.1 (2019-03-20)
- #455 Switch to
BigDecimal()
to avoid warnings in Ruby 2.6. - #457 When using an after callback on
execute
the:if
option does not see composed errors.
3.7.0 (2019-02-10)
- #454 Support for Rails 6.
- #435 Errors using the
:message
option were not properly merged.
3.6.2 (2018-08-21)
- #411 Cache the result of outcome validations. This also resolves duplicate callbacks on composed interactions.
3.6.1 (2017-11-12)
- #429 Pass details on translated detailed errors.
3.6.0 (2017-10-20)
- #422 A new
record
filter that accepts an object or calls a finder (e.g.find
) for the value passed. This is particularly useful for ActiveRecord objects. - #420 A
converter
option on theobject
filter that allows the value passed to be manually converted into an object of the correct type.
3.5.3 (2017-09-28)
- #425 where
given?
did not properly handle string keys for hashes with nested content
3.5.2 (2017-06-08)
- #417 - detailed errors added to
:base
are now properly merged
3.5.1 (2017-05-11)
- #415: Reserved input names no longer error. Instead they are ignored. This fixes an issue with Rails 5.1 where
:format
was part of the params input sent to the interaction.
3.5.0 (2017-03-18)
- #408:
given?
can now check for values in nested hashes within the input
3.4.0 (2016-10-20)
- #387: Added an option to the
integer
filter to allow specification of a base when converting strings.
- #384: Fixed wrapping
compose
call in an ActiveRecord transaction.
3.3.0 (2016-09-13)
- #383: Allowed
ActionController::Parameters
as the input toActiveInteraction::Base.run
. Previously onlyHash
was allowed.
3.2.1 (2016-08-26)
- #377: Fixed a bug that allowed interactions to define inputs the conflicted with
ActiveInteraction::Base
's methods. - #370: Improved the French translation. Thanks, @voondo!
3.2.0 (2016-06-07)
- #365: Updated boolean filter to accept
"on"
fortrue
and"off"
forfalse
. Thanks, @voondo!
3.1.1 (2016-05-31)
- #362: Added translation for Brazilian Portuguese.
- #364: Fixed a bug that prevented callbacks from being called by composed interactions that failed.
3.1.0 (2016-04-01)
- #357: Allowed default lambdas to take an optional filter argument.
3.0.1 (2016-01-15)
- #349: Merging errors on
:base
with a message that was aString
attempted to translate it.
3.0.0 (2016-01-13)
- #333: Copy symbolic errors when using
compose
.
Symbolic errors from composed interactions are now copied to their equivalently named filters on the parent interaction. This can cause some odd cases as noted in the the README.
2.2.0 (2015-12-18)
- #336: Added frozen string pragma for Ruby 2.3.
- #332: Changed default lambdas to be evaluated in the interaction's binding.
2.1.5 (2015-12-11)
- #330: Added a French translation.
2.1.4 (2015-11-03)
- #320: Stopped requiring ActiveRecord.
- #310: Added a warning when a filter is redefined.
- #311: Changed the error message when defining the default value for a hash.
2.1.3 (2015-10-02)
- #303: Allowed ActiveRecord associations as inputs to array filters.
- #304: Improved the error message for object filters when the class does not exist.
2.1.2 (2015-09-03)
- #298: Fixed a bug that raised exceptions when passing invalid nested values.
2.1.1 (2015-08-04)
- #296: Fixed a bug that silently converted invalid lazy default values to
nil
instead of raising anInvalidDefaultError
.
2.1.0 (2015-07-30)
- #295: Added
given?
predicate method to see if an input was passed torun
.
2.0.1 (2015-05-27)
- #286: Change
file
filter to check forrewind
instead ofeof?
. - #289: Actually removed
model
filter, which was deprecated in v1.6.0.
2.0.0 (2015-05-06)
- #250: Replaced symbolic errors with Rails 5-style detailed errors.
- #269: Prevented proc defaults from being eagerly evaluated.
- #264: Renamed
model
filter toobject
. - #213: Remove transaction support. Database transactions will need to be handled manually now.
- #214: Results are returned from invalid outcomes.
- #164: Changed the
hash
filter to use hashes with indifferent access. - #236: Changed the
file
filter to accept anything that responds toeof?
.
- #215: Rather than symbolizing keys all hashes now use indifferent access. This takes care of potential but unlikely DoS attacks noted in #163.
Please read through the Changed section for a full list of changes.
The contents of the execute
method are no longer wrapped in a transaction. You
can manually add a transaction if you need it by using
ActiveRecord::Base.transaction
. We've also removed the transaction
method since
it no longer has a use.
# v1.6
class Example < ActiveInteraction::Base
# This is the default.
transaction true
def execute
# ...
end
end
# v2.0
class Example < ActiveInteraction::Base
def execute
ActiveRecord::Base.transaction do
# ...
end
end
end
Symbolic errors should now be added with add
instead of add_sym
. Additionally,
you can view the errors with details
instead of symbolic
. This aligns with the
direction Rails is taking.
# v1.6
class Example < ActiveInteraction::Base
def execute
errors.add_sym :base, :invalid
errors.add_sym :base, :custom, '...'
end
end
Example.run.errors.symbolic
# => {:base=>[:invalid,:custom]}
# v2.0
class Example < ActiveInteraction::Base
def execute
errors.add :base, :invalid
errors.add :base, :custom, message: '...'
end
end
Example.run.errors.details
# => {:base=>[{:error=>:invalid},{:error=>:custom,:message=>'...'}]}
In the hash
filter we've stopped converting all inputs to symbols and instead we
now convert the hash to a hash with indifferent access. This means hash keys will
display as strings instead of symbols.
class Example < ActiveInteraction::Base
hash :options,
strip: false
def execute
options.keys
end
end
# v1.6
Example.run!(options: { enable: true })
# => [:enable]
# v2.0
Example.run!(options: { enable: true })
# => ["enable"]
We added the ability to return results from invalid interactions. Setting the result to
nil
was unnecessary. The right way to check for validity is to use valid?
. This change
allows you to return something from an interaction even if there are errors. This can be
very useful when updating an existing record.
class Example < ActiveInteraction::Base
def execute
errors.add(:base)
'something'
end
end
# v1.6
outcome = Example.run
outcome.valid?
# => false
outcome.result
# => nil
# v2.0
outcome = Example.run
outcome.valid?
# => false
outcome.result
# => "something"
When setting a default with a Proc
is is no longer eagerly evaluated.
class Example < ActiveInteraction::Base
boolean :flag,
default: -> {
puts 'defaulting...'
true
}
def execute
puts 'executing...'
end
end
# v1.6
# defaulting...
Example.run
# executing...
# v2.0
Example.run
# defaulting...
# executing...
1.6.1 (2015-10-02)
- #303: Allowed ActiveRecord associations as inputs to array filters.
1.6.0 (2015-05-06)
- Added
object
as an alias formodel
. - Added symbol support to
add
. - Added
details
as an alternative tosymbolic
.
- Deprecated
model
in favor ofobject
. - Deprecated
add_sym
in favor ofadd
. - Deprecated
transaction
. - Deprecated
symbolic
in favor ofdetails
.
1.5.1 (2015-04-28)
- #265: Allow
nil
inputs for interface and model filters. - #256: Improve error messages for nested invalid values.
1.5.0 (2015-02-05)
- #248: Add
has_attribute?
support to an instance of an interaction.
- #248: Fix support for simple_form gem.
1.4.1 (2014-12-12)
- #244: Fix improperly adding load paths to I18n.
1.4.0 (2014-12-10)
- #239: Accept
ActiveRecord::Relation
objects asarray
inputs.
1.3.1 (2014-12-10)
- #235: Fix a bug that prevented custom translations from loading.
- #224: Fix a bug that incorrectly inferred plural class names for filters inside arrays.
1.3.0 (2014-08-15)
- #178: Add an interface filter.
- #196: Add a
type_check
callback that happens before thevalidation
callback.
1.2.5 (2014-08-15)
- #207: Fix a bug that incorrectly converted plural class names to their singular form.
- #206: Fix a bug that caused an i18n deprecation warning.
- #201: Prevented time filters from being initialized with the format option when time zones are available.
1.2.4 (2014-08-07)
- #203: Fix a bug that prevented transaction options from being passed to subclasses.
1.2.3 (2014-05-12)
- #192: Fix a bug that raised
ActiveRecord::Rollback
when composing even when not in a transaction.
1.2.2 (2014-05-07)
- Fix a bug that raised
NameError
s when there were invalid nested hash errors. - Add missing translation for symbol filters.
1.2.1 (2014-05-02)
- #179: Fix a bug that marked model inputs as invalid even if they returned true
for
object.is_a?(klass)
.
1.2.0 (2014-04-30)
- #175: Add support for Rails-style date and time parameters like
date(1i)
. - #173: Add a decimal filter.
- #155: Add support for disabling and modifying transactions through the
transaction
helper method. - #140: Add support for
column_for_attribute
which provides better interoperability with gems like Formtastic and Simple Form.
1.1.7 (2014-04-30)
- #174: Fix a bug that leaked validators among all child classes.
1.1.6 (2014-04-29)
- #36: Fix a bug that caused nested hash error messages to be misleading.
1.1.5 (2014-03-31)
- The
transform_keys
method broke backwards compatibility because it's not available until Rails 4.0.2.
1.1.4 (2014-03-31)
- Fix an issue where non-stripped hash keys would be incorrectly converted to strings.
1.1.3 (2014-03-31)
- #165: Fix Rubocop errors and pin the version to avoid future issues with new cops breaking the build.
- #163: Fix some denial of service attacks via hash symbolization.
1.1.2 (2014-03-05)
- #156: Don't constantize classes for model filters on initialization. This fixes a bug that made those filters dependent on load order.
1.1.1 (2014-03-04)
- #153: Allow merging ActiveModel errors into ActiveInteraction errors with
ActiveInteraction::Errors#merge!
.
1.1.0 (2014-02-28)
- #116, #119, #122: Speed up many filters by caching class constants.
- #115: Add support for callbacks around
execute
. - #136: Allow callable defaults.
- #114: Support
:only
and:except
options simultaneously withimport_filters
. Previously this raised anArgumentError
. - #114: Support passing a single symbol to
:only
and:except
. Previously an Array was required.
- #138: Only set instance variables for attributes with readers defined.
1.0.5 (2014-02-25)
- #143: Rollback database changes when
compose
fails.
1.0.4 (2014-02-11)
- Add translations to the gem specification.
1.0.3 (2014-02-11)
- #135: Fix a bug that caused invalid strings to be parsed as
nil
instead of raising an error whenTime.zone
was set. - #134: Fix bug that prevented loading I18n translations.
1.0.2 (2014-02-07)
- #130: Stop creating duplicate errors on subsequent calls to
valid?
.
1.0.1 (2014-02-04)
- #125: Short circuit
valid?
after successfully running an interaction. - #129: Fix a bug that prevented merging interpolated symbolic errors.
- #128: Use
:invalid_type
instead of:invalid
as I18n key for type errors. - #127: Fix a bug that skipped setting up accessors for imported filters.
1.0.0 (2014-01-21)
- #102: Add predicate methods for checking if an input was passed.
- #103: Allow fetching filters by name.
- #104: Allow import filters from another interaction with
import_filters
.
- #111: Replace
Filters
with a hash. To iterate overFilter
objects, useInteraction.filters.values
. - Rename
Filter#has_default?
toFilter#default?
.
- #98: Add
respond_to_missing?
to complementmethod_missing
calls. - #106: When adding a filter that shares a name with an existing filter, it will now replace the existing one instead of adding a duplicate.
0.10.2 (2014-01-02)
- #94: Fix a bug that marked Time instances as invalid if Time.zone was set.
0.10.1 (2013-12-20)
- #90: Fix bug that prevented parsing strings as times when ActiveSupport was available.
0.10.0 (2013-12-19)
- Support casting "true" and "false" as booleans.
- #89: Fix bug that allowed subclasses to mutate the filters on their superclasses.
0.9.1 (2013-12-17)
- #84: Fix I18n deprecation warning.
- #82: Raise
ArgumentError
when running an interaction with non-hash inputs. - #77: For compatibility with
ActiveRecord::Errors
, support indifferent access ofActiveInteraction::Errors
. - #88: Fix losing filters when using inheritance.
0.9.0 (2013-12-02)
- Add experimental composition implementation (
ActiveInteraction::Base#compose
).
- Remove
ActiveInteraction::Pipeline
.
0.8.0 (2013-11-14)
0.7.0 (2013-11-14)
- #41: Add ability to chain a series of interactions together with
ActiveInteraction::Pipeline
.
0.6.1 (2013-11-14)
- Re-release. Forgot to merge into master.
0.6.0 (2013-11-14)
- Add ability to introspect interactions with
filters
. - #57: Allow getting all of the user-supplied inputs in an interaction with
inputs
. - #61: Add a symbol filter.
- #58: Allow adding symbolic errors with
errors.add_sym
and retrieving them witherrors.symbolic
.
- Error class now end with
Error
. - By default, strip unlisted keys from hashes. To retain the old behavior,
set
strip: false
on a hash filter. - #49: Prevent specifying defaults (other than
nil
or{}
) on hash filters. Set defaults on the nested filters instead. - #66: Replace
allow_nil: true
withdefault: nil
.
- Fix bug that prevented listing multiple attributes in a hash filter.
- Fix bug that prevented hash filters from being nested in array filters.
0.5.0 (2013-10-16)
- #34: Allow adding errors in
execute
method witherrors.add
.
- #56: Prevent manually setting the outcome's result.
0.4.0 (2013-08-15)
- Support i18n translations.
0.3.0 (2013-08-07)
- #30: Allow nested default values.
- #36: Give better error messages for nested attributes.
- #39: Add a more useful invalid interaction error message.
- #38: Use default value when given an explicit
nil
.
0.2.2 (2013-08-07)
- #40: Fix support for
ActiveSupport::TimeWithZone
.
0.2.1 (2013-08-06)
- #37: Fix setting a default value on more than one attribute at a time.
0.2.0 (2013-07-16)
- #23: Add support for strptime format strings on Date, DateTime, and Time filters.
- #20: Wrap interactions in ActiveRecord transactions if they're available.
- #24: Add option to strip string values, which is enabled by default.
0.1.3 (2013-07-16)
- Fix bug that prevented
attr_accessor
s from working. - Handle unconfigured timezones.
- #27: Use RDoc as YARD's Markdown provider instead of kramdown.
0.1.2 (2013-07-14)
- #29:
execute
will now have the filtered version of the values passed torun
orrun!
as was intended.
0.1.1 (2013-07-13)
- #28: Correct gemspec dependencies on activemodel.
0.1.0 (2013-07-12)
- Initial release.