Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[9.x] Adds implicit Enum route binding #40281

Merged
merged 7 commits into from
Jan 7, 2022

Conversation

nunomaduro
Copy link
Member

This pull request introduces implicit Enum route binding for Laravel v9.x. So let's see an example:

// Assuming the following `Enum`
enum Category: string
{
    case Fruits = 'fruits';
    case People = 'people';
}

// And assuming the following route;
Route::get('/categories/{category}', function (Category $category) {
    return $category->value;
});

// GET `/categories/fruits` returns `fruits`...
// GET `/categories/people` returns `people`...
// GET `/categories/cars` returns `404 Not Found`...

In other words, when the given argument matches one of the Enum cases, the code in this pull request will resolve the associated Enum for the route method / closure. Otherwise, will respond 404 Not Found, similar to Model route binding.

Route::get('/categories/{category}', function (Category $category) {
    dd($category);

    // ^ Illuminate\Tests\Integration\Routing\Category^ {#1220
    //  +name: "Fruits"
    //  +value: "fruits"
    // }
});

Now, it's important to keep in mind, that the given Enum needs to be a Backed Enum with a string backing type. Meaning that, the Enum header needs to look like this:

enum {{ EnumName }}: string

@taylorotwell taylorotwell merged commit 281ed58 into master Jan 7, 2022
@taylorotwell taylorotwell deleted the feat/implicit-backed-enum-route-binding branch January 7, 2022 04:26
@timmartin19
Copy link
Contributor

@nunomaduro is there a specific reason that an integer backed enum type can't be used?

taylorotwell added a commit to laravel/docs that referenced this pull request Mar 10, 2022
* Update routing.md

Added requirement of string-backed enums to "Implicit Enum Binding" as stated in laravel/framework#40281:

>Now, it's important to keep in mind, that the given Enum needs to be a Backed Enum with a string backing type. Meaning that, the Enum header needs to look like this:
>enum {{ EnumName }}: string

* Update routing.md

* Update routing.md

Co-authored-by: Taylor Otwell <[email protected]>
@lupinitylabs
Copy link
Contributor

@nunomaduro is there a specific reason that an integer backed enum type can't be used?

I was thinking the same. And patching the code to allow for int-backed Enums works like a charm, because tryFrom() automatically casts string numbers to integers.

However, if the user tries to pass a string like 'test' as a route parameter, it will cause a TypeError. Of course you could catch the error and fail route resolution, or have the user take care of that by making sure only numerics are allowed for the parameter, e.g. by using Route::get(...)->where(['enumParam' => '[0-9]+']), but I suppose for the sake of simplicity it was decided not to go down that rabbit hole.

However, I would love to see the docs being more explicit about this. It should be stated that Laravel allows you to type-hint a *string*-backed Enum only.

grafik

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants