Introducing the Laravel 5 Form Request Feature

  • November 20, 2014

Welcome to the incredibly popular Easy Laravel 5 companion blog. To celebrate the new edition's release (updated for Laravel 5.5!) use the discount code easteregg to receive 20% off the book or book/video package! » Buy the book

Laravel 5 introduces a new feature known as a form request. This feature is intended to remove form authorization and validation logic from your controllers by encapsulating this logic in a separate class. TODOParrot (Easy Laravel 5's sample project) uses form requests in conjunction with each form used throughout the site and I'm pleased to report this feature works meets its goal quite nicely. In this adapted book excerpt I'll introduce you to the Form Request feature by walking you through the creation of a form used to create a new TODO list. If you're new to Laravel this post should be pretty useful because it also demonstrates other key Laravel features such as how to create a form using the Form component, how to use the RESTful create and store actions, and how to save data.

Creating the Form

Before creating the form you'll first need to create the List controller's create view. Begin by creating a directory named lists, placing it in the directory resources/views. Inside this directory create a file named create.blade.php and add the following contents to it:

@extends('layouts.master')

@section('content')

<h1>Create a New List</h1>

<ul>
    @foreach($errors->all() as $error)
        <li>{{ $error }}</li>
    @endforeach
</ul>

{!! Form::open(['route' => 'lists.store', 'class' => 'form']) !!}

<div class="form-group">
    {!! Form::label('List Name') !!}
    {!! Form::text('name', null,
      ['class' => 'form-control',
       'placeholder' => 'San Juan Vacation']) !!}
</div>

<div class="form-group">
    {!! Form::label('List Description') !!}
    {!! Form::textarea('description', null,
      ['class' => 'form-control',
       'placeholder' => 'Things to do before leaving for vacation']) !!}
</div>

<div class="form-group">
    {!! Form::submit('Create List', ['class' => 'btn btn-primary']) !!}
</div>
{!! Form::close() !!}

@endsection

Presuming you've reviewed the earlier section regarding the contact form, then most of the form syntax is familiar to you. After creating the form, you'll need to modify the List controller's create action to serve the view:

public function create()
{
  return view('lists.create')->with('list', $list);
}

After saving the changes to the List controller, navigate to /lists/create and you should see the form presented in the below screenshot!

creating a new list

With the form in place and the create action updated, it's time to create the Form Request class used to validate the submitted form data.

Creating the List Form Request Class

In this section we'll create a form request that will be used to validate the form data. Begin by creating the form request class skeleton:

$ php artisan make:request ListFormRequest
Request created successfully.

Open the newly created form request class (app/Http/Requests/ListFormRequest.php) and you should see the following contents:

<?php

namespace App\Http\Requests;

use App\Http\Requests\Request;

class ListFormRequest extends Request {

  public function authorize()
  {
    return false;
  }

  public function rules()
  {
    return [
      //
    ];
  }

}

The rules method is used to define the validation rules which will be used in conjunction with the form fields. The list name and description are both logically required, so modify the method to look like this:

public function rules()
{
      return [
          'name'        => 'required',
          'description' => 'required'
      ];
}

The required validator used in this example is just one of many available via Laravel's validation class. See chapter 3 for more information about these rules. Incidentally, you can use multiple validators in conjunction with a form field by concatenating the validators together using a vertical bar (|). For instance if you wanted to validate a field used to pass an e-mail address you might define the validation rule as required|email.

You'll also want to modify the authorize method to return true instead of false, because at this point in time we're going to allow anybody to use the form without tying a list to a particular registered user (I'll show you how this is done in chapter 7):

public function authorize()
{
  return true;
}

Updating the List Controller's Store Action

All that remains is to update the List controller's store action to process the form contents. Of course, ListFormRequest handles the tiresome matter of validation, leaving us to focus solely on what to do with the data should it pass muster. In this instance all we need to do is save the data to the database, as demonstrated in the below revised store method:

use App\Todolist;
use App\Http\Requests\ListFormRequest;

...

public function store(ListFormRequest $request)
{

    $list = new Todolist([
        'name'        => $request->get('name'),
        'description' => $request->get('description')
    ]);

    $list->save();

    return \Redirect::route('lists.create',
      [$list->id])->with('message', 'Your list has been created!');

}

Notice we're referencing the ListFormRequest class at the top of the controller via use. This is important otherwise the store method will be unable to typecast the incoming $request.

Once the list is saved, user are redirected to the TODO list creation form should they desire to create another list right away.

Summary

Form requests can go a long way towards cleaning up your controllers and thanks to integration with Laravel's existing validation capabilities you have easy access to a wide range of validators. Give it a try, I think you'll like it!