Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

RushVan's avatar

Route model binding - use email as slug

I am trying use a provided email address to fetch a record and pass it to the edit view. I can do this with out issue using the id but can't with any other db values. From what i am understanding this is because the route resource default key is id. However, I thought this could be overridden using route model binding.

Here is my route.php

Route::bind('consumers', function($email) { return App\Consumer::where('email', $email)->first(); }); Route::resource('consumers', 'ConsumersController'); Route::get('consumers/{consumers}', 'ConsumersController@show');

and my Controller

public function show(Consumer $email)
{
    return view('consumers.edit', compact('consumer'));
}

In my RouterServiceProvider I have also added

$router->model('consumers', 'App\Consumer');

When I try this in the browser:

/consumers/edward.hunter@test.com

I get a NotFoundHttpException in Router.php line 927

I have tried this with other db fields like firstName thinking that the special characters in the email might be the cause. Nope, same result.

What am I missing?? Thanks!

0 likes
10 replies
usman's avatar

@Tenzing remove this line from your RouteServiceProvider and it should work:

$router->model('consumers', 'App\Consumer');

Usman.

martinbean's avatar

@Tenzing You can either manually fetch the model instance in your route service provider using the bind method:

$router->bind('consumers', function($email) {
    return Consumer::whereEmail($email)->firstOrFail();
});

Or if you’re absolutely certain you want to retrieve Consumer model instances by email instead of ID, then you can override the route key name in your model:

class Consumer extends Model
{
    public function getRouteKeyName()
    {
        return 'email';
    }
}
RushVan's avatar

Great. Thanks, I will give that a try.

RushVan's avatar

Ok, so. With some fighting I have gotten here now...

I have removed all model binding from RouteServiceProvider.php

This is my form action; {!! Form::open(['method' => 'GET', 'url' => 'consumers']) !!}

This is in my routes.php Route::resource('consumers', 'ConsumersController'); Route::get('consumers', 'ConsumersController@register');

This is in my ConsumersController.php public function register(Consumer $email) { $consumer = Consumer::where('email', '=', $email)->get();

    return view('consumers.register', compact($consumer));
}

This takes me to the view without error but when inspecting my query I see this; select * from consumers where email = '[]'

An empty array...same thing only with limit 1 appended if I use first();

RushVan's avatar

1/2 way there now...(I will post all the clean code from the solution for others once I get there).

I am now able to return the record associated with the $request->email. This returns an array of the consumers record. Now I want to pass this off to the register view so I can bind the model to the register form. However.

When I do this in my controller;

return view('consumers.register', compact($consumer));

and this in the view;

{{ Form::model($consumer) }}

I get this error:

Undefined variable: consumer (View: C:\xampp\htdocs\mhra\resources\views\consumers\register.blade.php)

I suspect this is because $consumer is an array and not an object?

Is there a way to strip our the consumers $id and pass that around??

RushVan's avatar

WOW!

return view('consumers.register', compact('consumer'));

NOT

return view('consumers.register', compact('$consumer'));
RushVan's avatar

Perhaps the 20 straight hours starring right at it weren't enough?? Brutal.

RushVan's avatar

Later than sooner here's hopin...

Thanks to all for the assistance and patience. Killer tool, super killer community.

I will post a full solution once I put the fire in my hair out.

Please or to participate in this conversation.