Skip to content

Support getRouteKey method from Laravel #817

@kaiserkiwi

Description

@kaiserkiwi

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions