-
Notifications
You must be signed in to change notification settings - Fork 269
Description
Description
In #315 you implemented the support for getRouteKeyName already. I am build an app currently that uses "self healing" URLs. (Aaron Francis made a good video about this) These have to use getRouteKey instead of getRouteKeyName as they're a bit more complex.
So what do I want to achieve? My Model has a slug and a uid that should make up the URL.
Example: https://example.com/team/super-team--VCT8MT
To achieve this in Laravel the code usually would look like this:
public function getRouteKeyName(): string
{
return 'uid';
}
public function getRouteKey(): string
{
return $this->slug . '--' . $this->getAttribute($this->getRouteKeyName());
}That's enough to build the URL with the route method from Laravel.
To Resolve the method we have to do a bit more, but it's quite easy to understand.
public function resolveRouteBinding($value, $field = null)
{
$uid = last(explode('--', $value)); // Get the id
$model = parent::resolveRouteBinding($id, $this->getAttribute($this->getRouteKeyName())); // Get the model by the defined route key name
if (! $model || $model->getRouteKey() === $value) { // If the model doesn't exist or the route key is already correct let Laravel do it's thing
return $model;
}
throw new HttpResponseException(
redirect()->route(request()->route()->getName(), $model), // If the URL is not the expected value, redirect to it
);
}The problem is, the URL Ziggy generates in this case is https://example.com/team/VCT8MT and not https://example.com/team/super-team--VCT8MT, as getRouteKey is currently not evaluated.
So instead of just $uid = last(explode('--', $value)); I have to write the following currently:
if (Str::contains($value, '--')) {
$uid = last(explode('--', $value));
} else {
$uid = $value;
}This way the URLs still work, but I have to redirect every call as the URLs from Ziggy don't have the expected format.
Suggestion
I think Ziggy should be able to evaluate getRouteKey the same way it evaluates getRouteKeyName. Or let's say it in other words: The same way Laravel evaluates the route definition.
Important to note is, that these two get used together in general. You still define the route key name but overwrite the actual path structure
Alternatives
I don't really see an alternative. As I described, the workaround is currently to generate the incomplete URLs and redirect to the expected one.