Closed smcabrera closed 2 years ago
This turns out to be an interesting issue. Prior to 4.0.0 we would populate the object with the raw value provided in the input and then override them with the filtered value. I think we did it that way at the time to preserve the raw values for use in errors but I don't exactly remember. The result of this is that in some cases what you noticed would work. The raw value given was available and used in the provided default proc and functioned correctly. This however, was luck.
Here's an example (using 3.8.3):
class Test < ActiveInteraction::Base
integer :a, default: -> { b + 1 }
integer :b
def execute
a
end
end
> Test.run!(b: 2) # => 3
> Test.run!(b: '2') # => TypeError (no implicit conversion of Integer into String)
This happens because the b
value was not converted into an integer so when we try to add 1
to it we get an error. If you flip the order of :a
and :b
it does work.
The real error here is that we wrote improper values in the first place. In a way this error was accidentally fixed in 4.0.0.
I'm sorry it caused confusion. That's certainly frustrating. I've thought about ways to help this and the best I can think of is to process the inputs first by filters without default procs, then any inputs passed, and finally filters that received no input and have a default proc. The issue is that we still have the same issue with any of those final filters with no inputs and default procs. We've shrunk the chances of it happening but it's much more confusing for someone to reason about and much more prone to failing in a surprising way. I think having them work in order is probably the best bet.
Similar but not identical to the issue https://github.com/AaronLasseigne/active_interaction/issues/507. Here it's not a matter of a circular dependency but the order that filters are added when using import filters or a module.
I have an example reproduction of this issue in this repo
Say we have an interaction like this
This interaction worked fine with active_interaction 3.8. However, in 4.1, we'll get an error:
We can fix this by changing the order of the filters, so this works
I was poking around in the code and it looks like this works because by the time the
title
proc is called theuser
is already available in the context so it's able to be used bytitle
, when previously it was not yet available since they're created in the order they appear in the file.Where it gets tricky is that we have some places in our code that share filters with each other through ImportFilters and including concerns. These sometimes break because it looks like a filter can be added in one place but even though it is overridden later, its key still now appears earlier in hash, which means it can still break some of our filters that are dependent in this way. For example
This fails the same was as previously noted even if we have
title
afteruser
in theCreatePost
interaction because it appears before the (non-existent)user
filter in the concern.It looks like this is fixed if we update the module to include an optional filter like this
This workaround is ok, and I'm not sure if there is a good way to better support this behavior in the library, but it's a bit of a surprising situation and it's something that appears to be broken when upgrading so at minimum maybe this edge case could be documented and a breaking change noted in the release notes?