Filtering transitions based on a model property.
stephan-v opened this issue ยท 3 comments
Reading the documentation I see that policies can be used to filter transitions based user roles for example.
I am wondering if there is an easier way when you simply want to check a property on a model though.
I have a Stop
model which can have a requires_identification
property set to true or false. If it is set to true I modify the transitions.
'callbacks' => [
'guard' => [
'guard_on_verifying' => [
'on' => 'verify',
'can' => 'verify',
],
],
],
Using the above code I am checking a StopPolicy
class which holds the following function:
public function verify(User $user, Stop $stop)
{
return $stop->requires_identification;
}
This works but it makes no sense because I am not doing user authorization. I am just checking a property on my model. Is there an easy way to improve this so I can just check a requirement on my model directly to ensure if the transition is allowed or not?
Thanks a lot.
Yes indeed, there is a simpler way for these kind of checks.
Using gates/policies is more useful when you want to do user authorizations.
But in your case, you need a simple guard callback. Here are some ways you can achieve this:
1. Using closures
'callbacks' => [
'guard' => [
'guard_on_verifying' => [
'on' => 'verify',
'do' => fn (Stop $stop) => $stop->requires_identification,
'args' => ['object'],
],
],
],
The do
key is the callback that checks the property, and the args
key is the arguments that will be passed to the callback. In this example object
will be evaluated to the Stop
instance that is inside the state machine.
2. Using a method on the model
Although I don't really like closures in configuration files, you could create a method on the Stop model, for example:
public function requiresIdentification(): bool
{
return $this->requires_identification;
}
'callbacks' => [
'guard' => [
'guard_on_verifying' => [
'on' => 'verify',
'do' => ['object', 'requiresIdentification'],
'args' => ['object'],
],
],
],
3. Using the property accessor
If you don't want to define a method on the model, you can call the property accessor on the model (getXAttribute), even if you haven't define an accessor. The accessor will return the value of the X Property.
'callbacks' => [
'guard' => [
'guard_on_verifying' => [
'on' => 'verify',
'do' => ['object', 'getRequiresIdentificationAttribute'],
'args' => ['object'],
],
],
],
4. Using boolval
The native boolval
function takes an argument and returns its boolean value. In this example, the callback is the boolval
function, and the args
is object.requires_identification
which will evaluate the value of the property on the model.
'callbacks' => [
'guard' => [
'guard_on_verifying' => [
'on' => 'verify',
'do' => 'boolval',
'args' => ['object.requires_identification'],
],
],
],
In the example 4, you can also use the value
or the with
helper functions in Laravel, instead of boolval
, which return the given argument as is.
Thanks a lot man, just what I am looking for. It's amazing to see how flexible this is. Keep up the good work.