Problems between checks within the same `input`
afuno opened this issue · comments
There is this code in the application:
class ApplicationService
include ServiceActor::Base
end
class CurrencyService < ApplicationService
input :currency,
type: String,
inclusion: {
in: %w[USD EUR],
message: ->(value:, **) { "Incorrect currency: #{value}" }
}
end
When using it:
CurrencyService.call(currency: :GBP)
Gives an error:
ServiceActor::ArgumentError: Incorrect currency: GBP
That is, the check for the type of the input value is ignored.
Perhaps this is an ordering issue. It looks like it would make sense to always have type
be called before inclusion
.
Would changing the order of the checks solve this for you?
In theory, it is correct to take the first check and fall immediately on it. If the first check passes, then take the second and fall on it. And so on until the end.
That is, there is not a problem in ordering, but a problem in the positioning of these checks. That is, first need to take the first rule and it doesn’t matter what it is - type or inclusion.
In theory need to add all the checks to an array and run them in a loop. But I'm not sure. 😬 Need to discuss the approach.
Oh, I see, you mean that input :currency, type: "String", inclusion: %w[A B]
would act differently to input :currency, inclusion: %w[A B], type: "String"
.
That would make total sense! However it would require rewriting how conditions are applied internally. I’d be happy to accept a pull-request going in this direction.
Or else, a smaller change that would fix this specific problem here would be to place base.include(ServiceActor::Conditionable)
before TypeCheckable
in lib/service_actor/base.rb
.
Here we are talking about all the checks, and not just about these two. Those two are just examples. In an amicable way it is necessary to introduce new logic. I'll try to provide a draft as soon as possible.
Released in v3.6.0