Laravel Route Model Binding Posted on February 25, 2016

Laravel's route model binding in 5.2 became even easier. To explain it let's take a look at this simple code:

// routes.php
Route::get('post/{id}', array(
    'as'   => 'post.view',
    'uses' => 'PostController@view')
)->where('id', '[0-9]+');

// PostController.php
public function view($id)
{
    $post = Post::findOrFail($id);
    return view('post.view', ['post' => $post]);
}

You can see in this example we have our route as well as our controller. Now this isn't anything new however, take the following example below.

// routes.php
Route::get('post/{post}', array(
    'as'   => 'post.view',
    'uses' => 'PostController@view')
);

// PostController.php
public function view(\App\Post $post)
{
    return view('post.view', ['post' => $post]);
}

Now you can see that we have explicitly told Laravel that we are expecting a Post (model) variable, and we do not have to manually query for that model. Laravel is smart enough to know that we want an eloquent object of our post model, so it will do a findOrFail($id) for us automatically. This is just magical and saves so much time. However, this got me thinking that it needs to be taken a step further. I cannot be the ONLY one who likes control on where to send their users when something happens instead of a generic 404 page.

Laravel's Generic 404 (Sorry / Whoops) Page

When you are writing your Laravel application you probably came across this once or 10 hundred times when something didn't go right in your application. This is exactly what should happen, and when you change your .env file's debug variable to false Laravel will throw a 404 error instead of the "Whoops" page.

This means that if we are looking up a post with the following code $post = Post::findOrFail($id);

When there is an error such as the post we are looking for cannot be found, Laravel will throw the Whoops (if in debug) or a 404 when in production.

Users are human beings

Well everyone knows that. All our user are human beings (at least for now) and I find it funny how even some times the most skilled developers over look the need of their users. As humans we like to know what is going on. If something fails we like to know it and some of us like to know the reason why.

Let's take a look at this code example (route and controller)

// routes.php
Route::get('post/{id}', array(
    'as'   => 'post.view',
    'uses' => 'PostController@view')
)->where('id', '[0-9]+');

// PostController.php
public function view($id)
{
    $post = Post::where('id', $id)->first();

    if(! $post)
    {
        return Redirect::route('posts')->withErrors(['The post you were looking for cannot be found']);
    }

    return view('post.view', ['post' => $post]);
}

You can see here if the model is not found we send our user back to a different page (not 404) with a specific error message. Yes a few more lines of code, but this give you (the developer) control of where to send you users. Most of the time we hope that the user doesn't come to a page not found, or click on a record that doesn't exists... but if they do it is nice to show them a little feed back.

To read that "error" variable you would use the session.

@if(count($errors) > 0)
    <div class="alert alert-danger">
        <ul>
            @foreach ($errors->all() as $error)
                <li>{{ $error }}</li>
            @endforeach
        </ul>
    </div>
@endif

Thanks for reading

Share this post