I spent this afternoon trying to replace my series of chain-of-responsibility validators with a #laravel pipeline…but think it is wrong to do so as I am not sure how to break out of the pipe on the first validation failure. Ideas on how to do this are appreciated #php
@grmpyprogrammer oh, alternatively, what about using first? The callback returns the first object that meets a condition. So you could call first on the validator collection, returning true when the validator is not valid. You could then access the messages on the returned validator, or know that all the validators have passed if no result is returned.
@grmpyprogrammer could you use a collection of validators and call each on them with a callback that returns the result of validation? Each will stop executing if false is returned.
Accessing the validation messages could then be achieved by filtering the collection to retrieve messages.
@grmpyprogrammer What do the validators look like now? Sounds to me like maybe monad would do exactly what you want. (Or a result monad, if you care about the error messages.)
@Crell they are objects that have the same four public methods on them — I want to execute validate() then isValid() and then if isValid() is false, stop the chain and return what validationMessage() returns. Each validator has some common elements for the constructor but often needs more stuff than the basics
@Crell and then I want to execute them in a chain, one after another and stopping on any failures. My chain-of-responsibility implementation was slightly flawed and was repeating validations
@grmpyprogrammer Yes, a maybe or result monad would do that. Or, rather, it would still step over the later items but skip over them.
Other option is a psr14 dispatcher, or something modeled on it. The StoppableEventInterface seems close to what you want to do. See the dispatcher in Crell/Tukio for an example.
@Crell Since this is a Laravel app, I was hoping to lean on stuff like native pipeline + native collections but having never implemented that stuff before I’m blocked
@grmpyprogrammer perhaps you could implement a pattern where failure throws? That should bubble up control flow. A very light wrapper around the core pipelines could make it automatic.
Add comment