Charts in Laravel 5.1 with Morris.js

Access all tutorials in sprocket icon.

August 22, 2015 from author Bill Keck.

Charts in Laravel 5.1

Charts are great way to spice up UI and the Morris.js Chart is fairly easy to implement, so that is what we are going to use for our lesson.

This tutorial builds on the following tutorials:

You don’t need to use a Morris.js chart with our Widget model, but it does make it easy to follow along for the data formatting part.

Part 1. The Chart

We’re going to build a chart for our index page in our Widget model, which is just a generic model that I’m using in my tutorials. We have a Widget model, a WidgetController and corresponding views, including an index view and a search results view named resultsindex.

This means we can have a chart for all records, which are displayed on the index view and also a chart for specific search results, which are displayed on the resultsindex view.

We’re going to start with the views and work our way backwards. Let’s look at our views/widget/index view:



@extends('layouts.master')

@section('title')

    <title>The Widget Page </title>

   @endsection

@section('css')

    <link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/morris.js/0.5.1/morris.css">

@endsection

@section('content')

   {!! Breadcrumb::withLinks(['Home' => '/', 'Widgets' => '/widget']) !!}

   @include('widget.noresults')

    <br>

   @include('widget.searchform')

   @if(isset($results))

       @include('widget.searchresults')

       @else

        <h1>Widget Stats </h1>

        // insert a div id with a value of chart

        <hr>

       @include('widget.allrecords')

       @endif

@endsection

@section('scripts')

    //cdnjs.cloudflare.com/ajax/libs/raphael/2.1.0/raphael-min.js
    //cdnjs.cloudflare.com/ajax/libs/morris.js/0.5.1/morris.min.js

    

       function ConfirmDelete()
       {
           var x = confirm("Are you sure you want to delete?");
           if (x)
               return true;
           else
               return false;
       }

    
    
       var data =  ;

       Morris.Line({
           element: 'chart',
           data: data,
           xkey: 'year',
           ykeys: ['count'],
           labels: ['widgets created']
       });
    

@endsection

Note: Once again wordpress is chomping my code. So you have to insert a div id with a value of chart where I have indicated // insert a div id with a value of chart.

It’s also missing the opening and closing script tags within the @section(‘scripts’), so you will have to add those as well.

I have created a gist with the full code for reference and convenience to copy.

Also note that if you are not using the Bootstrapper package, then chop out:

{!! Breadcrumb::withLinks([‘Home’ => ‘/’, ‘Widgets’ => ‘/widget’]) !!}

Ok, let’s look at the parts that are specific to the Morris Chart implementation. We’ll start with pulling in the css through CDN:



@section('css')

    <link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/morris.js/0.5.1/morris.css">

@endsection

Since we have an @yield(‘css’) on our Master page, the contents inside the @section(‘css’) tags will be injected, so we have our css.

Next we have within our @section(‘content’), our h1 tag and chart div:



 <h1>Widget Stats </h1>

        // insert a div id with a value of chart

        <hr>

Note: Once again wordpress is chomping my code. So you have to insert a div id with a value of chart where I have indicated // insert a div id with a value of chart.

Here again is the gist with the full code for reference and convenience to copy.

I use a simple <hr> to separate from the rest of the content, so nothing fancy about that. Our chart div is where the actual chart will go. You can see I’m specifying height.

Next we have our @section(‘scripts’), which is where we will bring in the morris.js files via CDN:



@section('scripts')

    //cdnjs.cloudflare.com/ajax/libs/raphael/2.1.0/raphael-min.js
    //cdnjs.cloudflare.com/ajax/libs/morris.js/0.5.1/morris.min.js

Then we have a script for our alert on the delete button, which has nothing to do with chart so I’m going to skip it. That brings us to the script for the chart:



    
       var data =  ;

       Morris.Line({
           element: 'chart',
           data: data,
           xkey: 'year',
           ykeys: ['count'],
           labels: ['widgets created']
       });
    

@endsection

Don’t forget to add the opening and closing script tags.

You can see we are setting var data the result of json encoded $chartData. Before we encode it, it looks like this:



array:4 [▼
  0 => array:2 [▼
    "year" => "2012"
    "count" => "3"
  ]
  1 => array:2 [▼
    "year" => "2013"
    "count" => "1"
  ]
  2 => array:2 [▼
    "year" => "2014"
    "count" => "3"
  ]
  3 => array:2 [▼
    "year" => "2015"
    "count" => "45"
  ]
]

This is what it looks like after json encoding:



[{"year":"2012","count":"3"},
{"year":"2013","count":"1"},
{"year":"2014","count":"3"},
{"year":"2015","count":"46"}]

So obviously our $chartData is returning year and the count of widgets created within that year. You make a chart from any data you like, you just need to format it correctly in json format.

Next we have the config:



 Morris.Line({
           element: 'chart',
           data: data,
           xkey: 'year',
           ykeys: ['count'],
           labels: ['widgets created']
       });

Morris.Line will display the results as a line chart, while Morris.Bar will display it as bar chart. We are assigning the results to the chart element, which in our implementation is a div id.

Next we are using the data variable that we created as the source of the data. Then we assign the year key to the xkey and the count to ykeys. We designate the labels to say widgets created.

And that’s pretty much all you need on the morris.js side of the equation, which makes this so easy to work with. For those of you who know how to do the queries on your model to produce the $chartData results, you probably don’t need to continue.

One thing to note however is that the Morris.Line implementation, as opposed the .Bar implementation, requires all data to be of type string. Since I’m not a javascript wizard, I did the conversion before encoding $chartData. You can handle that however you wish.

The implementation resultsindex view is exactly the same as for index, so just repeat the steps from above, if you are following along with the Widget model and views. Since it is the same, you can also extract it out to a partial, but I will leave that up to you to implement.

Part 2. Building a Chart Helper

So the second part of this tutorial deals with extracting the $chartData from the model. This got a little complicated because of the formatting issues, where the year has to be a string, which made it bloat the controller.

Because of that, I extracted it out to a helper class. Basically, I wanted to be able to get the chart data with a single line in the controller:



$chartData = $chart->chartDataFromAllRecords();

To be able to use $chart, which is an instance of our WidgetChart class, I inject the instance into the method like so:



public function index(WidgetChart $chart)
{

One of the really cool features in Laravel 5.1 is that it will instantiate the instance for you, as long as you have included the use statement:



use App\Charthelpers\WidgetChart;

So there is no need to new up an instance of the class, Laravel does it for you.

For reference, I’m going to give you the entire index method from the WidgetController. This is so if you are following along from the earlier tutorials, you can see exactly how I use it:



public function index(WidgetChart $chart)
{

  $widgets = Widget::paginate(10);

   $count =  DB::table('widgets')->count();

  if (session()->has('message')){

      Session::flash('noResults', 'Sorry, we found 0 results');
   }

   $chartData = $chart->chartDataFromAllRecords();


   return view('widget.index', compact('widgets', 'count', 'chartData'));
}

So just 3 variables sent to the view, a paginated instance of Widget, the count of all records, and $chartData.

If you haven’t been following the other tutorials and this doesn’t make sense to you, it’s ok. The important part is how we are using our instance of WidgetChart to send along $chartData.

Ok, since we have not yet created the helper class, let’s do it now. Within your app folder, create a folder named CharHelpers. Inside the ChartHelpers folder, create a php file named ChartHelper.php, with the following contents:



 <?php
namespace App\ChartHelpers;

use App\Widget;
use DB;

class WidgetChart
{

   public function chartDataFromAllRecords()
   {

       $yearCounts = Widget::select(DB::raw('year(created_at) as year'),
           DB::raw('count(widget_name) as `count`'))
           ->groupBy('year')
           ->having('year', '>', '2011')->get();

       $chartData = $this->formatResultOf($yearCounts);

       return $chartData;

   }

   public function chartDataFrom($searchTerm)
   {

           $yearCounts = Widget::select(DB::raw('year(created_at) as year'),
               DB::raw('count(widget_name) as `count`'))
               ->where('widget_name', 'LIKE', '%'. $searchTerm .'%')
               ->groupBy('year')
               ->get();

           $chartData = $this->formatResultOf($yearCounts);

           return $chartData;

   }

   protected function convertToString($results)
   {
       foreach ($results as $key => $val)
       {

           foreach ($val as $k => $v)
           {


               if (is_numeric($v))
               {

                   $results[$key][$k] = (string) $v;

               }

           }
       }

       return $results;
   }

   /**
    * @param $yearCounts
    * @return mixed
    */
   private function formatResultOf($yearCounts)
   {
       $results = $yearCounts->toArray();

       $chartData = $this->convertToString($results);

       return $chartData;
   }


}

You can see our namespace declaration, use statements, and class declaration:



namespace App\ChartHelpers;

use App\Widget;
use DB;

class WidgetChart
{

First we have our chartDataFromAllRecords method:

public function chartDataFromAllRecords()
   {

       $yearCounts = Widget::select(DB::raw('year(created_at) as year'),
           DB::raw('count(widget_name) as `count`'))
           ->groupBy('year')
           ->having('year', '>', '2011')->get();

       $chartData = $this->formatResultOf($yearCounts);

       return $chartData;

   }

We call the select method on the Widget model and then we are using DB::raw, so we can use raw sql to get what we need. In this case, we want the created_at date returned in a year format, labeled as year, and we also want a count of widgets, and we group everything by year. We also set a condition of having year > 2011, which means any widgets before 2011 will not be included. I figured I would throw in an example of that as an extra tip. The results get assigned to $yearCounts.

Next we use our formatResultOf method to format $yearCounts and assign it to $chartData, which we then return. Two things have to happen, first we need the results in an array, second, we need the year to be a string. So inside the formatResultOf method:



private function formatResultOf($yearCounts)
{
   $results = $yearCounts->toArray();

   $chartData = $this->convertToString($results);

   return $chartData;
}

We format the $yearCounts object as an array and assign it to the variable $results. Then we feed $results into our convertToString method:



protected function convertToString($results)
{
   foreach ($results as $key => $val)
   {

       foreach ($val as $k => $v)
       {


           if (is_numeric($v))
           {

               $results[$key][$k] = (string) $v;

           }

       }
   }

   return $results;
}

Don’t you just love nested foreach loops? In this case, $val is an array, so to get to our year, we need to check if $v is_numeric, and if so, cast it to a string, using (string). I always get tripped up on the array syntax, but this is correct:



$results[$key][$k] = (string) $v;

So with each pass, it puts the value into the array as a string. Then we simply return the array as $results.

Getting back to our formatResultsOf method, which uses the convertToString method as follows:



$chartData = $this->convertToString($results);

We now have our $chartData in a format that can be converted to json, so we simply return it:



return $chartData;

So that covers what we need when we want to return all results from the model for the chart, but in our case, we also have a second method for returning the results of a search, which takes in $searchterm as a parameter:



public function chartDataFrom($searchTerm)
{

       $yearCounts = Widget::select(DB::raw('year(created_at) as year'),
           DB::raw('count(widget_name) as `count`'))
           ->where('widget_name', 'LIKE', '%'. $searchTerm .'%')
           ->groupBy('year')
           ->get();

       $chartData = $this->formatResultOf($yearCounts);

       return $chartData;

}

You can see the only difference is that we have the where clause:



->where('widget_name', 'LIKE', '%'. $searchTerm .'%')

If you are following along with the WidgetController, I have made a gist for the search method, so you can see how we have used the chartDataFrom method.

That concludes the WidgetChart class. You can see this ended up being more than what we would want in our controller, and formatting results is not the responsibility of the controller.

We could have gone even further by coding to contract instead of a concrete class. We could have set up a contracts folder within the ChartHelpers folder, and then within that made a ChartHelpersContract.

If you would like to go in that direction, check out my tutorial on how to setup a service provider, and implement a service provider for the ChartHelpersContract.

In my case, I didn’t feel it was necessary for my application, but you should decide what is right for you.

I hope you have enjoyed this tutorial and found it useful. Click on the sprocket icon at the top of the page to see all tutorials.

Please comment, share, and like if you can, thanks!

I don’t have a donate button, but If you would like to support my work, you can do so by buying one of my 99¢ books, I really appreciate it.

Advertisements

Handling Exceptions and Custom Exceptions in Laravel 5.1

Access all tutorials in sprocket icon.

August 19, 2015 from author Bill Keck.

Handling Exceptions & Custom Exceptions in Laravel 5.1

One of the more intimidating aspects of learning programming for me has been throwing exceptions, when to do it, how to do it, etc. They just seem scary for whatever reason, but last night I watched a great video on Laracasts about them.

While the video was very informative, it didn’t show me exactly how to setup a custom exception in Laravel 5.1, so I thought this would make a great tutorial.

Out of the box, Laravel 5.1 comes with an Exceptions folder that sits in the app folder. Within that is the Handler.php file, which we can modify to handle all exceptions, including any custom exceptions we want to throw. This is Handler.php file you get with the standard install:



<?php

namespace App\Exceptions;

use Exception;
use Symfony\Component\HttpKernel\Exception\HttpException;
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;

class Handler extends ExceptionHandler
{
   /**
    * A list of the exception types that should not be reported.
    *
    * @var array
    */
   protected $dontReport = [
       HttpException::class,
   ];

   /**
    * Report or log an exception.
    *
    * This is a great spot to send exceptions to Sentry, Bugsnag, etc.
    *
    * @param  \Exception  $e
    * @return void
    */
   public function report(Exception $e)
   {
       return parent::report($e);
   }

   /**
    * Render an exception into an HTTP response.
    *
    * @param  \Illuminate\Http\Request  $request
    * @param  \Exception  $e
    * @return \Illuminate\Http\Response
    */
   public function render($request, Exception $e)
   {
       return parent::render($request, $e);
   }
}

Probably the most common exception we come across is the ModelNotFoundException, which is going to get thrown if you type an id into the url that doesn’t exist. For example:



yourproject.com/widget/15

If there is no widget record 15, you will get the ModelNotFoundException, which is very helpful to a programmer, but is not what we want the end user to see. So we have to handle this exception when it’s thrown in a way that is digestible to the end user.

To do this, we are going to modify Handler.php to the following:



<?php

namespace App\Exceptions;

use Exception;
use Symfony\Component\HttpKernel\Exception\HttpException;
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
use Illuminate\Database\Eloquent\ModelNotFoundException;

class Handler extends ExceptionHandler
{
   /**
    * A list of the exception types that should not be reported.
    *
    * @var array
    */
   protected $dontReport = [
       HttpException::class,
   ];

   /**
    * Report or log an exception.
    *
    * This is a great spot to send exceptions to Sentry, Bugsnag, etc.
    *
    * @param  \Exception  $e
    * @return void
    */
   public function report(Exception $e)
   {
       return parent::report($e);
   }

   /**
    * Render an exception into an HTTP response.
    *
    * @param  \Illuminate\Http\Request  $request
    * @param  $e
    * @return \Illuminate\Http\Response
    */
   public function render($request, Exception $e)
   {
       switch($e){

           case ($e instanceof ModelNotFoundException):

               return $this->renderException($e);
               break

           default:

               return parent::render($request, $e);

       }
   }

   protected function renderException($e)
   {

      switch ($e){

          case ($e instanceof ModelNotFoundException):
              return response()->view('errors.404', [], 404);
              break;

          default:
              return (new SymfonyDisplayer(config('app.debug')))
                     ->createResponse($e);

      }

   }


}

You can see that we have set up a switch statement in our render method to determine which kind of exception we are throwing:



 switch($e){

           case ($e instanceof ModelNotFoundException):

               return $this->renderException($e);
               break

           default:

               return parent::render($request, $e);

       }

So we either determine it’s a ModelNotFoundExcpeption or not. The reason I’m using a switch statement here is that I want to make it easy to add other exceptions, which we will show an example of shortly.

If it is a ModelNotFoundExcpeption, then we call the renderException method, which has it’s own switch statement:



switch ($e){

          case ($e instanceof ModelNotFoundException):
              return response()->view('errors.404', [], 404);
              break;

          default:
              return (new SymfonyDisplayer(config('app.debug')))
                     ->createResponse($e);

      }

Obviously, with one exception type, this isn’t really necessary, you could just return the view in the render method. But I’m doing it this way to give myself flexibility as I build out my application.

So now we have a way to handle a ModelNotFoundExcpeption, but we don’t have the corresponding view. So let’s create that now.

Laravel 5.1 comes with an errors folder located in resources/views. Inside the errors folder, create a errors.404.blade.php file with the following contents:



@extends('layouts.master')

@section('content')

//use bootstrap alert div with dismissible

Oh Snap! We can't find what you are looking for...

//end alert div

@endsection

Note: for some reason wordpress has decided to chomp my escape tags, so you are not seeing the HTML for the above. Instead, I’m just including comments for the bootstrap alert div. For your convenience, I’ve linked to the alert markup from the getBootstrap site, so you can just grab it from there.

I have also created a gist so you can get the full code there.

Also note I’m assuming you have a master.blade.php file located in a folder named layouts. If you don’t know what a master page is, please check out my tutorial on Creating A Master Page.

Ok, so that is all you need to run something like:



yourproject.com/widget/78

Assuming there is no widget 78, you will get the nicely formatted exception. You can adjust your error message however you wish.

Ok, so how do we add a custom exception? I don’t have a use case for one, so I’m just going to pick something out of the air and call it ReallyFriendlyException. Let’s create a ReallyFriendlyException.php file in our Exceptions folder with the following contents:



<?php

namespace App\Exceptions;

class ReallyFriendlyException extends \Exception
{


}

Note the namespace. You will have to pull in the correct use statement in our Handler.php file, which can be difficult to debug if you have typos. Just a heads up there.

In this case, we are keeping it super simple, and we don’t even need anything in our class.

Next we need to modify our Handler.php file to the following:



<?php

namespace App\Exceptions;

use Exception;
use App\Exceptions\ReallyFriendlyException;
use Symfony\Component\HttpKernel\Exception\HttpException;
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
use Illuminate\Database\Eloquent\ModelNotFoundException;

class Handler extends ExceptionHandler
{
   /**
    * A list of the exception types that should not be reported.
    *
    * @var array
    */
   protected $dontReport = [
       HttpException::class,
   ];

   /**
    * Report or log an exception.
    *
    * This is a great spot to send exceptions to Sentry, Bugsnag, etc.
    *
    * @param  \Exception  $e
    * @return void
    */
   public function report(Exception $e)
   {
       return parent::report($e);
   }

   /**
    * Render an exception into an HTTP response.
    *
    * @param  \Illuminate\Http\Request  $request
    * @param  $e
    * @return \Illuminate\Http\Response
    */
   public function render($request, Exception $e)
   {
       switch($e){

           case ($e instanceof ModelNotFoundException):

               return $this->renderException($e);
               break;

           case ($e instanceof ReallyFriendlyException):

               return $this->renderException($e);
               break;

           default:

               return parent::render($request, $e);

       }
   }

   protected function renderException($e)
   {

      switch ($e){

          case ($e instanceof ModelNotFoundException):
              return response()->view('errors.404', [], 404);
              break;

          case ($e instanceof ReallyFriendlyException):
              return response()->view('errors.friendly');
              break;
          default:
              return (new SymfonyDisplayer(config('app.debug')))
                     ->createResponse($e);

      }

   }


}

So in the above, we added a case statement in both methods. In the render method, we added:



case ($e instanceof ReallyFriendlyException):

               return $this->renderException($e);
               break;

And in the renderException method, we added:



case ($e instanceof ReallyFriendlyException):
              return response()->view('errors.friendly');
              break;

So you can see how easy it will be to add and handle exception types to our application. We don’t have the view errors.friendly yet, so let’s make an friendly.blade.php file in our errors folder with the following contents:



@extends('layouts.master')

@section('content')

//div for bootstrap dismissable alert

 Oh Snap! You threw a Really Friendly Exception...


//end alert div

@endsection

Again note: For some reason wordpress has decided to chomp my escape tags, so you are not seeing the HTML for the above. Instead, I’m just including comments for the bootstrap alert div. For your convenience, I’ve linked to the alert markup from the getBootstrap site, so you can just grab it from there.

I have also created a gist with the full code.

Now to demonstrate, I’m just going to go to one of my controllers and pop it into the create method, since that is a one line method:



public function create()
{
   throw new ReallyFriendlyException;
   //return view('widget.create');
}

And now we can test it:



yourproject.com/widget/create

And you should get your ReallyFriendlyException. It’s really very simple. Now obviously you could do more with it, optimize the code, etc., but this just gives you an idea of how it all stitches together and how easy it is to create your own custom exceptions in Laravel 5.1.

I hope you have enjoyed this tutorial and found it useful. Click on the sprocket icon at the top of the page to see all tutorials.

Please comment, share, and like if you can, thanks!

I don’t have a donate button, but If you would like to support my work and learn more about Laravel, you can do so by buying one of my books, Laraboot: laravel 5* For Beginners, I really appreciate it.

Creating Views in Laravel 5.1

Access all tutorials in sprocket icon.

August 18, 2015 from author Bill Keck.

Creating Views in Laravel 5.1

Please note that this tutorial builds on previously tutorials, which, if you want to follow along exactly, you should read first:

Also note that your actual workflow may differ from the tutorials, it is not necessary to adopt a workflow that creates a model first for example. I only did it this way to make it easy for me to demonstrate. Different developers have their own approaches, so you will have to determine that for yourself.

So from our Restful Controller Tutorial, we have a WidgetController with 8 methods:

  • index
  • create
  • store
  • show
  • edit
  • update
  • destroy
  • search

I added the 8th method, search, so that is not a standard method that you get when you create a controller using artisan. Of the methods that come out-of-the-box, the following would have corresponding views:

  • index
  • show
  • create
  • edit

The destroy method is more of an action, it doesn’t require a dedicated view, so it is not on the list.

Typically, an index view is used to show a list of results. The show view is often used to show the details of an individual record. The create method typically shows a form for creating a new record, and edit shows a form for updating a specific record.

Now if you are building an application with multiple models, as most applications will have, then you need to create a folder within the views folder with the name of the model you are building views for. In our case, this will be the widget folder, so go ahead and create that now.

If we didn’t have a folder for our views within the views folder, we would only be able to use the filename index once, which is not what we want. Obviously, we are following a pattern, and we want to be able to use this pattern for all models.

You probably know by now that views use the blade template engine. Blade is a fantastic templating engine that provides us with easy to use syntax, allowing us to mix php and html much more easily than we could without it. We will see this in action in a minute.

Another benefit to Blade is that it compiles the files into standard PHP, so you don’t incur server overhead by using it. This is just awesome.

The Blade file names follow this convention:



index.blade.php
show.blade.php

Anyway, you get the idea. Without further ado, create a widget folder in the views folder. Then you need to create an index.blade.php file within that folder. Then change the index.blade.php file to:



@extends('layouts.master')

@section('title')

    <title>The Widget Page </title>

   @endsection

@section('content')

   {!! Breadcrumb::withLinks(['Home' => '/', 'Widgets' => '/widget']) !!}

   @include('widget.noresults')

    <br>

   @include('widget.searchform')

   @if(isset($results))

       @include('widget.searchresults')

       @else

       @include('widget.allrecords')

       @endif

@endsection

@section('scripts')
    <script>

       function ConfirmDelete()
       {
           var x = confirm("Are you sure you want to delete?");
           if (x)
               return true;
           else
               return false;
       }

    </script>

@endsection

Let’s just knock this down one line at a time. We start with:



@extends('layouts.master')

The @extends allows us to inject the pieces of our view into a master page. In this case, we are telling it we want to extend layouts.master. The layouts folder is inside the views folder if you have followed the tutorial on creating a Master page. And the actual master page is master.blade.php.

For more information on creating a Master page, please see my tutorial on Master pages.

Next we add an @section tag, which let’s us insert a section into the Master page:



@section('title')

    <title>The Widget Page </title>

   @endsection

So in the Master page, there is an @yield(‘title) tag, and this is where this section is injected. In this case, we want the <title> </title> for this page.

Next we have an opening @section(‘content’) tag. Everything that falls between @section(‘content’) and @endsection(‘content’) will be injected into @yield(‘content’) in the master page.

After the opening @section(‘content’), we have:



   {!! Breadcrumb::withLinks(['Home' => '/', 'Widgets' => '/widget']) !!}

If you have the Laravel Bootstrapper package installed, this prints a beautiful Bootstrap breadcrumb to the view. If you don’t have it, you can get the installation instructions from my top 10 Laravel packages tutorial. If you don’t want to use it, just chop it out.

Next we have:



  @include('widget.noresults')

    <br>

Here we are including a view partial. This include statement is calling noresults.blade.php inside of the widget folder, which is inside the view folder.

Since that doesn’t exist, let’s create it now. Place the following in noresults.blade.php:



 @if (Session::has('noResults'))

    <div class="alert alert-error" role"alert">{{ Session::get('noResults') }} </div>

   {{  session()->forget('noResults') }}

@endif

Ok, this walks us right into a control structure using Blade. Referencing the WidgetController index method:



public function index()
{

  $widgets = Widget::paginate(10);

   $count =  DB::table('widgets')->count();

  if (session()->has('message')){

      Session::flash('noResults', 'Sorry, we found 0 results');
   }

   return view('widget.index', compact('widgets', 'count'));
}

You can see we are passing noResults via session. The point is that if noResults is present in the session, we show an alert:



  <div class="alert alert-error" role"alert">{{ Session::get('noResults') }} </div>

That is Bootstrap alert with Blade syntax echoing the Session value of ‘noResults.’ Everything between the {{ }} is an echo statement for php. You can see how clean and readable that is.

When you need to echo without escaping html, use {!! !!}. We will see an example of that soon.

The last thing we do in the if statement is unset the session:



{{  session()->forget('noResults') }}

The purpose of the noresults.blade.php view partial is to produce the ‘Sorry, we found 0 results’ message when there are no results from a search query.

Just to keep it clear, let’s look at the partial again:



 @if (Session::has('noResults'))

    <div class="alert alert-error" role"alert">{{ Session::get('noResults') }} </div>

   {{  session()->forget('noResults') }}

@endif

The reason why we extracted this is to keep our code in index.blade.php as clean as possible. It also allows for reuse of code. If we had several models that used a session to return a no results message, we could put the view partial in a folder named partials, then reuse it for multiple views. This cuts down on code duplication and is ultimately much easier to maintain.

Ok, back on index.blade.php, our next line is:



@include('widget.searchform')

So what we have here is a view partial for the search form. Since we don’t have that file yet, let’s go ahead and create searchform.blade.php now:



 <div class="panel-group" id="accordion" role="tablist" aria-multiselectable="true">
    <div class="panel panel-default">
        <div class="panel-heading" role="tab" id="headingOne">
            <h4 class="panel-title">
                <a role="button" data-toggle="collapse" data-parent="#accordion" href="#collapseOne" aria-expanded="false" aria-controls="collapseOne">
                    <span class="glyphicon glyphicon-search" aria-hidden="true"> </span> Search
                </a>
            </h4>
        </div>
        <div id="collapseOne" class="panel-collapse collapse " role="tabpanel" aria-labelledby="headingOne">
            <div class="panel-body">
                <h1> Search For a Widget </h1>

                <hr/>

               @include('errors.errors')

                <form class="form-horizontal" role="form" method="POST" action="/widget/search">
                    <input type="hidden" name="_token" value="{{ csrf_token() }}">

                    <div class="form-group">
                        <label class="col-md-4 control-label">Enter Widget Name </label>
                        <div class="col-md-6">
                      <input type="text" class="form-control" name="widget_name" value="" required>
                        </div>
                    </div>

                    <div class="form-group">
                        <div class="col-md-6 col-md-offset-4">
                           <button type="submit" class="btn btn-primary">
                               Search
                            </button>


                        </div>
                    </div>
                </form>
            </div>
        </div>
    </div>


 </div>

 <br>

Most of this is straight Bootstrap. I added a glyphicon to the label on the panel. Keep in mind when you see all this put together, that frontend development is not a core strength for me. I’ve tried to keep it as simple as possible.

Please note that in order for this to work, your master page will have to reference Bootstrap’s dependencies. You can check out my Master Page Tutorial for details on that.

So we added the form within the panel-body tag. You can see we are calling a partial errors.errors. If you don’t have that, let’s make the errors folder within the views directory now. Then within that, place the errors.blade.php with the following contents:



@if (count($errors) > 0)
    <div class="alert alert-danger">
        <strong>Whoops! </strong> There were some problems with your input. <br> <br>
        <ul>
           @foreach ($errors->all() as $error)
                <li>{{ $error }} </li>
           @endforeach
        </ul>
    </div>
@endif

So here we have another if statement. The $errors object is always available to the view. So in this case, we are checking if the count is greater than 0, and if so, we display the message and iterate through the errors, using blade’s foreach syntax.

Interspersed php and html can be a real mess. Blade’s intuitive syntax just makes it incredibly easy to read and a pleasure to work with.

Ok, so that’s the errors.errors view partial, which we can use whenever we have a form that can possibly return errors, such as invalid input or empty fields that need to be required.

You can see that we are nesting partials, and just how effective and focused this code is. Separating the code like this makes it way easier to work on and maintain in the long run.

Getting back to the searchform.blade.php partial, we open the form:



  <form class="form-horizontal" role="form" method="POST" action="/widget/search">

In the action, we are listing the url that matches a route that we created for widget/search. Next:



   <input type="hidden" name="_token" value="{{ csrf_token() }}">

You can see that we included csrf_token via the blade syntax:



{{ csrf_token() }}

We only have one input for our form, I kept it simple. Most forms will have more than one field.



 <div class="form-group">
          <label class="col-md-4 control-label">Enter Widget Name </label>
          <div class="col-md-6">
          <input type="text" class="form-control" name="widget_name" value="" required>
          </div>
  </div>

This is Bootstrap form syntax. You can see I added the name of the attribute, widget_name and placed required at the end of the tag. This will force it to have a value before being submitted.

The last thing of note is the submit button:



 <div class="form-group">
        <div class="col-md-6 col-md-offset-4">
        <button type="submit" class="btn btn-primary">
          Search
        </button>

 </div>
 </div

And that’s pretty much all there is to it. You can see again how having this extracted to a view partial keeps view code from being overwhelmed with spaghetti.

Ok, let’s go back to index.blade.php, the next line is:



@if(isset($results))

       @include('widget.searchresults')

       @else

       @include('widget.allrecords')

       @endif

So this is a if statement that checks to see if there are results from a search query. If $results, then we get the widget.searchresults partial, if we don’t have results from a search, we show the widget.allrecords partial instead.

I liked doing it this way because it is so readable and clean. The heavy, messy html has been extracted out to 2 different files. Let’s create searchresults.blade.php with the following:



 <div>
    <div class="panel panel-default">
        <!-- Default panel contents -->
        <div class="panel-heading">{{ $count }} Widgets Found </div>
        <div class="panel-body">
            <a href="/widget/create">
                <button type="button" class="btn btn-lg btn-success">
                   Create New
                </button>
            </a>
        </div>

        <!-- Table -->
        <table class="table">
            <tr>

                <th>Id </th>
                <th>Name </th>
                <th>Edit </th>
                <th>Delete </th>

            </tr>

           @foreach($results as $result )

                <tr>
                    <td>{{ $result->id }}  </td>
                    <td> <a href="/widget/{{ $result->id }}">{{ $result->widget_name }} </a> </td>

                    <td> <a href="/widget/{{ $result->id }}/edit">
                            <button type="button" class="btn btn-default">Edit </button>
                        </a> </td>
                    <td>{!! Form::model($result, ['route' => ['widget.destroy', $result->id],
                       'method' => 'DELETE'
                       ]) !!}
                        <div class="form-group">

                           {!! Form::submit('Delete', array('class'=>'btn btn-danger', 'Onclick' => 'return
                           ConfirmDelete();')) !!}

                        </div>
                       {!! Form::close() !!}
                    </td>
                </tr>
           @endforeach

        </table>

        <div>

        </div>
    </div>
 </div>

This is a basic Bootstrap panel with a table popped inside. You can see in the panel-heading that we echo a $count variable sent from the controller to let us know how many results we have.

Then we have a create button:



 <a href="/widget/create">
                <button type="button" class="btn btn-lg btn-success">
                   Create New
                </button>
            </a>

This route has already been provided by the Route Resource from our previous Route Resource tutorial.

Next we get the table heading:



 <!-- Table -->
        <table class="table">
            <tr>

                <th>Id </th>
                <th>Name </th>
                <th>Edit </th>
                <th>Delete </th>

            </tr>

You can see we are going to have an id column, a name column, an edit column, and a delete column.

Next we have the main part of the table:



@foreach($results as $result )

                <tr>
                    <td>{{ $result->id }}  </td>
                    <td> <a href="/widget/{{ $result->id }}">{{ $result->widget_name }} </a> </td>

                    <td> <a href="/widget/{{ $result->id }}/edit">
                            <button type="button" class="btn btn-default">Edit </button>
                        </a> </td>
                    <td>{!! Form::model($result, ['route' => ['widget.destroy', $result->id],
                       'method' => 'DELETE'
                       ]) !!}
                        <div class="form-group">

                           {!! Form::submit('Delete', array('class'=>'btn btn-danger', 'Onclick' => 'return
                           ConfirmDelete();')) !!}

                        </div>
                       {!! Form::close() !!}
                    </td>
                </tr>
           @endforeach

        </table>

Obviously, each pass of the foreach loop creates the table rows. You can see the Blade syntax in the td tags. For the delete button, we actually have a form because for security purposes, delete has to come via post, not a get request.

Also note, the @foreach loop is using the $results object that is returned from our search method in the WidgetController.

So that is the interesting part of that view partial.

Next we go back to index.blade.php to the call to include allresults.blade.php. Since we have not made that partial, let’s do that now. Create allresults.blade.php with the following:



 <div>
    <div class="panel panel-default">
        <!-- Default panel contents -->
        <div class="panel-heading">{{ $count }} Widgets </div>
        <div class="panel-body">
            <a href="/widget/create"> <button type="button" class="btn btn-lg btn-success">
                   Create New </button> </a>
        </div>

        <!-- Table -->
        <table class="table">
            <tr>

                <th>Id </th>
                <th>Name </th>
                <th>Edit </th>
                <th>Delete </th>

            </tr>
           @foreach($widgets as $widget )

                <tr>
                    <td>{{ $widget->id }}  </td>
                    <td> <a href="/widget/{{ $widget->id }}">{{ $widget->widget_name }} </a> </td>

                    <td>  <a href="/widget/{{ $widget->id }}/edit">
                            <button type="button" class="btn btn-default">Edit </button> </a> </td>
                    <td>{!! Form::model($widget, ['route' => ['widget.destroy', $widget->id],
                       'method' => 'DELETE'
                       ]) !!}
                        <div class="form-group">

                           {!! Form::submit('Delete', array('class'=>'btn btn-danger', 'Onclick' => 'return ConfirmDelete();')) !!}

                        </div>
                       {!! Form::close() !!} </td>
                </tr>
           @endforeach
        </table>
        <div>

           {!! $widgets->render() !!}

        </div>
    </div>
 </div>

This is very similar to the searchresults partial, except we are using a $widgets object instead of $results. The other difference is that we include:



  {!! $widgets->render() !!}

This for the pagination method that returns the results in groups of 10 records per page. Since we now have the allresults.blade.php separated out as a partial, we can refine it how we wish.

Ok, let’s go back to index.blade.php. For easy reference, let’s look at the content section:



@section('content')

   {!! Breadcrumb::withLinks(['Home' => '/', 'Widgets' => '/widget']) !!}

   @include('widget.noresults')

    <br>

   @include('widget.searchform')

   @if(isset($results))

       @include('widget.searchresults')

       @else

       @include('widget.allrecords')

       @endif

@endsection

Ok, we wrap it up by using the @endif tag and then the @endsection tag.

The last part of index.blade.php is a little piece of javascript that we use to put an alert on the delete button, so that users don’t accidentally delete records by clicking the button:



@section('scripts')
    <script>

       function ConfirmDelete()
       {
           var x = confirm("Are you sure you want to delete?");
           if (x)
               return true;
           else
               return false;
       }

    </script>

@endsection

You can see we are using the scripts section, which will get injected into @yield(‘scripts’) in the Master page. You don’t have to put the actual script in here, it could easily be a call to public/js folder, if that is the name and path of where you keep your javascript files.

Anyway, that wraps up our index.blade.php and related view partials. All we have left is create.blade.php, show.blade.php, and edit.blade.php.

Let’s start with create.blade.php:



@extends('layouts.master')

@section('title')
    <title>Create a Widget </title>
   @endsection

   @section('content')

       {!! Breadcrumb::withLinks(['Home' => '/', 'Widgets' => '/widget', 'Create']) !!}

        <h1>Create a New Widget </h1>


        <hr/>

       @include('errors.errors')


       {!! Form::open(array('url' => '/widget', 'class' => 'form')) !!}

        <!-- widget_name Form Input -->
        <div class="form-group">
           {!! Form::label('widget_name', 'Widget Name') !!}
           {!! Form::text('widget_name', null, ['class' => 'form-control']) !!}
        </div>

        <div class="form-group">

           {!! Form::submit('Create Widget', array('class'=>'btn btn-primary')) !!}

        </div>

       {!! Form::close() !!}



       @endsection

So this is a very simple form with one input. We are using Bootstrapper’s form helper to open the form:



{!! Form::open(array('url' => '/widget', 'class' => 'form')) !!}

Note that we’re using the {!! !!} which doesn’t escape HTML because we want it to print the form html. It’s all incredibly easy to understand.

Next is the edit.blade.php file, which we need to make now:



@extends('layouts.master')

@section('title')
    <title>Edit a Widget </title>
   @endsection

   @section('content')

       {!! Breadcrumb::withLinks(['Home' => '/', 'Widgets' => '/widget', $widget->widget_name]) !!}

        <h1>Update {{ $widget->widget_name }} </h1>


        <hr/>

       @include('errors.errors')


       {!! Form::model($widget, ['route' => ['widget.update', $widget->id],
       'method' => 'PATCH',
       'class' => 'form',
       ]) !!}

        <!-- widget_name Form Input -->
        <div class="form-group">
           {!! Form::label('widget_name', 'Widget Name') !!}
           {!! Form::text('widget_name', null, ['class' => 'form-control']) !!}
        </div>

        <div class="form-group">

           {!! Form::submit('Update Widget', array('class'=>'btn btn-primary')) !!}

        </div>

       {!! Form::close() !!}

       @endsection

This is almost the same as the create.blade.php partial, but we use the Bootstrapper form helper to do a form model binding:



{!! Form::model($widget, ['route' => ['widget.update', $widget->id],
       'method' => 'PATCH',
       'class' => 'form',
       ]) !!}

So this will put the old value of widget_name in the form for reference. Also note, the method is set to PATCH, which is not supported by HTML, but Laravel makes the conversion for us.

The first parameter of the model method is the model, in this case $widget. Then we get the route, along with the model id, in this case $widget->id.

And now to finish up our Views tutorial, we will create the show view:



@extends('layouts.master')

@section('title')
    <title>{{ $widget->widget_name }} </title>
   @endsection

@section('content')
   {!! Breadcrumb::withLinks(['Home' => '/', 'Widgets' => '/widget', $widget->widget_name => $widget->id]) !!}
    <br>
    <div>
        <div class="panel panel-default">
            <!-- Default panel contents -->
            <div class="panel-heading">{{ $widget->widget_name }} Widget </div>
            <div class="panel-body">
                <a href="/widget/create"> <button type="button" class="btn btn-lg btn-success">
                       Create New </button> </a>
            </div>

            <!-- Table -->
            <table class="table">
                <tr>

                    <th>Id </th>
                    <th>Name </th>
                    <th>Edit </th>
                    <th>Delete </th>

                </tr>


                    <tr>
                        <td>{{ $widget->id }}  </td>
                        <td>{{ $widget->widget_name }} </td>

                        <td>  <a href="/widget/{{ $widget->id }}/edit">
                                <button type="button" class="btn btn-default">Edit </button> </a> </td>
                        <td>{!! Form::model($widget, ['route' => ['widget.destroy', $widget->id],
                           'method' => 'DELETE'
                           ]) !!}
                            <div class="form-group">

                               {!! Form::submit('Delete', array('class'=>'btn btn-danger', 'Onclick' => 'return ConfirmDelete();')) !!}

                            </div>
                           {!! Form::close() !!} </td>
                    </tr>

            </table>

        </div>
    </div>

@endsection
@section('scripts')
    <script>

       function ConfirmDelete()
       {
           var x = confirm("Are you sure you want to delete?");
           if (x)
               return true;
           else
               return false;
       }

    </script>

@endsection

You can see that we are again using the small piece of javascript as an alert. You should probably extract that out to separate file to avoid duplication. I will leave that for you to implement.

This is pretty much like our allresults.blade.php file, except we don’t have a foreach loop because there is only going to be one row of results.

The $widget object holds the correct model instance from the show method in the WidgetController.

I hope you have enjoyed this tutorial and found it useful. Click on the sprocket icon at the top of the page to see all tutorials.

Please comment, share, and like if you can, thanks!

I don’t have a donate button, but If you would like to support my work, you can do so by buying one of my 99¢ books, I really appreciate it.

Restful Controller in Laravel 5.1

Access all tutorials in sprocket icon.

August 17, 2015 from author Bill Keck.

Restful Controller in Laravel 5.1.

Please note that this tutorial references some of other tutorials. Here is a short list of the other tutorials you may want to read before this one:

We are using my Widget model in this tutorial, which is also referenced in the tutorials mentioned above. I recommend create the Widget model and routes to more effectively follow this tutorial.

With a restful controller, you get basic functionality for things like creating, reading, updating and deleting records. These are common tasks that you will have to do with most models you create. This is why I created the generic Widget model, so we can play with common functionality, and you can use this approach in the future for your projects.

A restful controller will have the following 7 methods:

  • index
  • show
  • create
  • store
  • edit
  • update
  • destroy

Now the good news is that Laravel 5.1 has built-in generators to create the controller, so you don’t have to memorize a long list of methods, it’s all there for you when you create it. So let’s make our controller.

Go to the command line and run:



php artisan make:controller WidgetController

That will get you the following file, which is in app/Http/Controllers/WidgetController.php:



 <?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

use App\Http\Requests;
use App\Http\Controllers\Controller;

class WidgetController extends Controller
{
   /**
    * Display a listing of the resource.
    *
    * @return Response
    */
   public function index()
   {
       //
   }

   /**
    * Show the form for creating a new resource.
    *
    * @return Response
    */
   public function create()
   {
       //
   }

   /**
    * Store a newly created resource in storage.
    *
    * @param  Request  $request
    * @return Response
    */
   public function store(Request $request)
   {
       //
   }

   /**
    * Display the specified resource.
    *
    * @param  int  $id
    * @return Response
    */
   public function show($id)
   {
       //
   }

   /**
    * Show the form for editing the specified resource.
    *
    * @param  int  $id
    * @return Response
    */
   public function edit($id)
   {
       //
   }

   /**
    * Update the specified resource in storage.
    *
    * @param  Request  $request
    * @param  int  $id
    * @return Response
    */
   public function update(Request $request, $id)
   {
       //
   }

   /**
    * Remove the specified resource from storage.
    *
    * @param  int  $id
    * @return Response
    */
   public function destroy($id)
   {
       //
   }
}

You can see that these are empty stubs. They perfectly match our route resource that we created in our Route Resource Tutorial.

The workflow is fast and quick with the artisan generators. We’re going to add one more method, so you can stub it out now if you wish:



public function search(Request $request)
{

	//search widget model and return results

}

To avoid doing a super long tutorial all in one go, we’re going to build out our controller, then deal with the views in a separate tutorial.

I’m going to start with the search method, since that is the most complicated one on our controller.

The purpose of the search controller is to manage the POST request from a search form that searches the widgets table for results that are like the input string in the search box. In order for the POST to work, we will have to add the following route:



Route::post('widget/search', 'WidgetController@search');

Next, let’s change the search method on the controller to:



public function search(Request $request)
{
   $this->validate($request, [
       'widget_name' => 'required|alpha_num|max:20',

   ]);

   $searchterm = $request->widget_name;

       $widgets = DB::table('widgets');
       $results = $widgets->where('widget_name', 'LIKE', '%'. $searchterm .'%')
             ->get();


   if (count($results) > 0){

       $count = count($results);

       return view('widget.resultsindex', compact('results', 'count'));
       
   }

       return Redirect::route('widget.index')->with('message', ['Sorry, no results!']);


}

Since we’re dealing with a POST request, we want an instance of the request object handed into the signature like so:



public function search(Request $request)

We follow that with validation of the request:



 $this->validate($request, [
       'widget_name' => 'required|alpha_num|max:20',

   ]);

Note that the $this->validate method is always available to the controller. We hand in the instance of the request object, $request, and also an array of the key value pairs of the input name and the corresponding validation rules.

You can see that we want the input required, to be limited to alphanumeric, and to have a maximum of 20 characters. You can find a complete list of validation rules in the Laravel Docs, if you need other rules.

Next we assign a variable name to the request value:



$searchterm = $request->widget_name;

Then we create our object that pulls all results:



$widgets = DB::table('widgets');

Then we query for results, using LIKE, so we can anything that is like our $searchterm:



$results = $widgets->where('widget_name', 'LIKE', '%'. $searchterm .'%')->get();

The Laravel syntax is so intuitive, it is easier to follow than my written explanations. What a great framework.

So now we have $results holding our search results. We will test to see if there is anything there, and if so, send the user to a view that shows the results, and if not, we send them to the index method, with a message that no results were returned.

You will understand the intent of this when it’s all put together, but for now, imagine an index page for widgets that lists all the widgets. There is a search window on the page. If you use the search and there are results, you go to the results page. If there are no results, we go back to the index page, with a message telling us there are no results.

Let’s take a look at what this looks like:



if (count($results) > 0){

   $count = count($results);

   return view('widget.resultsindex', compact('results', 'count'));
   
}

   return Redirect::route('widget.index')->with('message', ['Sorry, no results!']);

You can see we are also setting a $count variable if there are results that we will send to the view. This is so we can display the number of results.

Of course this is just one implementation, not necessarily the best implementation. There are a lot of different ways to do this and you could implement the repository pattern for example. We’re not doing that here, but that will be the subject of a separate tutorial.

Also, as a side note, I couldn’t get pagination to work on my view partial, so until I solve that problem, I have left it out. I expect to fix it, so check back in the future for that.

One last thing to note here is that when there are no results, we attach a flash message, with a key of message, which is how we are going to let the index method know that it needs to do something if a search was executed and didn’t return results.

If you are not following the intent here exactly, don’t worry it will make more sense when you put it all together with the views.

I could have made this simpler by skipping search, but I felt like it was a nice addition because you are going to want to search your model records in most cases.

Anyway, let’s move on to the index method:



public function index()
{

  $widgets = Widget::paginate(10);

   $count =  DB::table('widgets')->count();

  if (session()->has('message')){

      Session::flash('noResults', 'Sorry, we found 0 results');
   }

   return view('widget.index', compact('widgets', 'count'));
}

For index, we want to return all widget records, paginated at 10 records per page. Can the syntax get any easier?

Next we hold the count of the records in $count.



   $count =  DB::table('widgets')->count();

Next we check to see if there is a ‘message’ in session, and if so, flash it into the session here, so we can pass it to the view:



  if (session()->has('message')){

      Session::flash('noResults', 'Sorry, we found 0 results');
   }

Then finally, we return to the view, using the compact function to pass our objects along:



return view('widget.index', compact('widgets', 'count'));

Note the syntax of the view method, widget.index. The widget in this case refers to a folder inside of views, and index is inside the widget folder.

Remember, I will be providing the views in a separate tutorial, so you will see how all this plays out.

Ok, next up we have the create method, which shows us the create form:



public function create()
{
   return view('widget.create');
}

You can see we are just returning a view for the form.

In restful controllers, there is a separate method for storing the form data:



public function store(Request $request)
{
   $this->validate($request, [
       'widget_name' => 'required|unique:widgets|alpha_num|max:20',

   ]);

   $widget = Widget::create(['widget_name' => $request->widget_name]);
   $widget->save();

   return Redirect::route('widget.index');

}

You can see we are taking in the request object, and running it through a validator:




$this->validate($request, [
       'widget_name' => 'required|unique:widgets|alpha_num|max:20',

   ]);

What’s different here than when we did it with search is that now we have to enforce the unique rule because we don’t want different widgets with the same name. When you see unique:widgets, that widgets part is the name of the table.

Next we create our instance of the model:



$widget = Widget::create(['widget_name' => $request->widget_name]);

Then we save it to the DB:



$widget->save();

Again, thanks to Laravel’s incredibly intuitive syntax, this is all just ridiculously easy.

Finally we return to the index page:



 return Redirect::route('widget.index');

Alternatively, you could go to the show page for the individual record, but I decided not to do that here.

Next we have the show method:



public function show($id)
{
   $widget = Widget::findOrFail($id);

   return view('widget.show', compact('widget'));
}

We hand in the id of the record we want, then use the findOrFail method to return it. Why findOrFail? Because it will return a ModelNotFound exception, which we can handle a certain way, so the user experience is good one. We will cover that in a separate tutorial.

Then we just return the result to the show view:



 return view('widget.show', compact('widget'));

Next we have the edit method, that returns the edit form:



public function edit($id)
{
   $widget = Widget::findOrFail($id);

   return view('widget.edit', compact('widget'));
}

We hand in the id of the record we are looking for, do a findOrFail, then return it to the view so we can bind it to the form.

To process the edit form, we need the update method:



public function update(Request $request, $id)
{
   $this->validate($request, [
       'widget_name' => 'required|unique:widgets|alpha_num|max:20',

   ]);
   $widget = Widget::findOrFail($id);
   $widget->update(['widget_name' => $request->widget_name]);


   return Redirect::route('widget.show', ['widget' => $widget]);
}

In this case, we are handing both the request object and the id. Then we validate the POST:



  $this->validate($request, [
       'widget_name' => 'required|unique:widgets|alpha_num|max:20',

   ]);

Next we find the model instance:



$widget = Widget::findOrFail($id);

Then we update using the value from the request object:



$widget->update(['widget_name' => $request->widget_name]);

Finally, we redirect to the show view, passing in the model instance:



return Redirect::route('widget.show', ['widget' => $widget]);

Ok, so the last method we have is the destroy method:



public function destroy($id)
{
   Widget::destroy($id);

   return Redirect::route('widget.index');
}

We use a model method, destroy, to delete the record of the id that we handed in. Then we simply redirect where we want, in this case, to the index page.

And that’s it for our Restful widget controller. I’ll follow this up with tutorial on the views within a few days, so you will understand all of this fully when you put it all together.

I hope you have enjoyed this tutorial and found it useful. Click on the sprocket icon at the top of the page to see all tutorials.

Please comment, share, and like if you can, thanks!

I don’t have a donate button, but If you would like to support my work and learn more about Laravel, you can do so by buying one of my books, Laraboot: laravel 5* For Beginners, I really appreciate it.

Route Resource in Laravel 5.1

Access all tutorials in sprocket icon.

August 15, 2015 from author Bill Keck.

How to create a route resource in Laravel 5.1

This tutorial builds on the model creation tutorial, so you might want to look at that as well.

Laravel has excellent documentation on routing, so I won’t go over it all here. You can also check out great free videos on Laracasts on routes.

But I do want to cover a basic route resource in case you are following along in some of the other tutorials, especially the one where we are making a generic Widget model. I’m calling it Widget because I need something generic for demonstration purposes.

Ok, so let’s create a route resource, this is going to be really difficult. Go to app/Http/routes.php and open it, then add the following route:



Route::resource('widget', 'WidgetController');

Ok, so not really difficult, in fact it’s just one line. Now if you have not created a WidgetController, it will complain when you try to run at the command line:



php artisan route:list

So if you have not created WidgetController, let’s do so now, using artisan from the command line:



php artisan make:controller WidgetController

And just like that we have our controller. But we’re not going to focus on that, since this is a tutorial about route resource.

Anyway, if you now run from the command line:



php artisan route:list

You can see you have 8 routes, which map perfectly to the restful WidgetController. So with this one line of code, we will be able to go to our create, store, edit, update, destroy, show, and index methods on the controller.

You can see the different types of requests. Create, for example, is get. This will simply return a view that displays a form. The store route is a post request. This method on the controller will accept the form post from the create page and store it in the DB.

The edit route is a get request and the controller returns the edit form. The update route is a post request and maps to the update method on the controller, which will store the changes in the DB. The destroy route sends us to the destroy method and that is for deleting records.

The show and index routes are get requests. Index is typically used to return a list of results and show is for individual records.

This is just a brief introduction. I really recommend the Laracast’s video on routing and the Laravel docs for more info. What we did here is just enough to get started.

I hope you have enjoyed this tutorial and found it useful. Click on the sprocket icon at the top of the page to see all tutorials.

Please comment, share, and like if you can, thanks!

I don’t have a donate button, but If you would like to support my work and learn more about Laravel, you can do so by buying one of my books, Laraboot: laravel 5* For Beginners, I really appreciate it.

Using Model Factory to make Test Data in Laravel 5.1

Access all tutorials in sprocket icon.

August 14, 2015 from author Bill Keck.

Making Test Data with Model Factory in Laravel 5.1*

We’re going to look at 2 ways to use the Model factory that ships with Laravel to create test records that we can play with for our Widget model.

Incidentally, if you want to see a cool video on this, check out the Laracast’s free video, Jeffery Way does an excellent job of teaching this. And just as a side note. I highly, highly recommend Laracasts as the best source of free and paid tutorials on Laravel anywhere. Our company even bought a company license so all our programmers can watch it. Jeffery is not paying me to say this, but I just can’t recommend it highly enough. You will love it.

Please note that we use the Widget model from our making a model in Laravel tutorial, so you should do that tutorial before moving on to this one.

Ok, let’s get started. Let’s open database/factories/ModelFactory.php. You can see that it comes with a factory method to seed the users table:



$factory->define(App\User::class, function ($faker) {
   return [
       'name' => $faker->name,
       'email' => $faker->email,
       'password' => str_random(10),
       'remember_token' => str_random(10),
   ];
});

You’ll note that we are using the faker library, which gets handed in as $faker. So this is all built for us out of the box and it’s incredibly simple. To run this, you would have had to run the initial migrations that come with Laravel 5.1, so that you have the database to insert the records to.

For now we are going to comment out this function and replace it with:



$factory->define(App\Widget::class, function ($faker) {
   return [
       'widget_name' => $faker->unique()->word,

   ];
});

To populate our widget_name column in our widgets table, we are going to use a faker word, making sure that it is unique, since we have that constraint on our db column.

You can check with the fzaninotto/Faker Git page for a full set of formatters you can play with, it’s pretty awesome.

Now to run this using the db:seed method via artisan, we first have to go to our database/seeds folder and open DatabaseSeeder.php, and change it to:



<?php

use Illuminate\Database\Seeder;
use Illuminate\Database\Eloquent\Model;
use App\Widget;

class DatabaseSeeder extends Seeder
{
   /**
    * Run the database seeds.
    *
    * @return void
    */
   public function run()
   {
       Model::unguard();

       Widget::truncate();

       factory(Widget::class, 50)->create();

       Model::reguard();
   }
}

Inside the factory method, we hand in the appropriate model, in this case Widget, and we tell it how many records we want, in this case 50.

Then you would just go to your command line and, don’t do this yet, type the following:



php artisan db:seed

That’s pretty simple. Now if you did this, even though I said not to, and you want to get rid of the records, you could roll back the migration, assuming that you have not migrated anything else since you migrated up the widgets table:



php artisan migrate:rollback

The reason I recommended not using db:seed is there is a better way to do this, a tip I picked up from Laracasts. We can actually write a php unit test that will give us the option of whether or not to save the records, so we can see them first.

If you are completely unfamiliar with unit testing, don’t worry, I have a gentle introduction to unit testing that you can do before moving on. If you don’t normally follow TDD, it’s ok, but I would definitely recommend learning at least minimal testing practices and fortunately, Laravel makes this incredibly easy for you.

So I’m going to move assuming that you either know how to use php unit with Laravel or that you have checked out my tutorial and are ready to go.

So what we’re going to do is go into tests/ExampleTest.php and make a copy of that file named WidgetTest.php. Then let’s modify WidgetTest.php to the following:



<?php

use Illuminate\Foundation\Testing\WithoutMiddleware;
use Illuminate\Foundation\Testing\DatabaseMigrations;
use Illuminate\Foundation\Testing\DatabaseTransactions;
use App\Widget;

class WidgetTest extends TestCase
{

   use DatabaseTransactions;

   /**
    * A basic functional test example.
    *
    * @return void
    */
   public function testWidgetFactory()
   {
       $widgets = factory(Widget::class, 50)->create();
       dd($widgets);
   }
}

So here we have made a simple test that calls the factory method to create our widget records. Since we are using:



use DatabaseTransactions;

The records won’t actually persist to the DB. And since we are using:



 dd($widgets);

The test will print out the objects.

So when you have this ready, just run php unit from the command line like so:



vendor/bin/phpunit

Like I mention in my php unit tutorial, if that path doesn’t work, try:



vendor/phpunit/phpunit/phpunit

Ok, so to persist the test records to the DB, just comment out Database Transactions like so:



// use DatabaseTransactions;

Now when you have the faker records in there, and you try to run the test a second time, you may get an error due to the unique constraint. That’s because faker doesn’t know what is already in your db. So if you need to run the test again, roll back the migration or drop the table manually first, then you can run it again.

And that’s it! You now have 2 ways to populate your DB with test data using model factories.

I hope you have enjoyed this tutorial and found it useful. Click on the sprocket icon at the top of the page to see all tutorials.

Please comment, share, and like if you can, thanks!

I don’t have a donate button, but If you would like to support my work and learn more about Laravel, you can do so by buying one of my books, Laraboot: laravel 5* For Beginners, I really appreciate it.

How to Make a Model in Laravel 5.1

Access all tutorials in sprocket icon.

August 14, 2015 from author Bill Keck.

How to Make a Model in Laravel 5.1

In order to follow along with this tutorial, you will have to have already done the install laravel tutorial and the database setup tutorial.

So we’re going to tackle something really basic by making a Widget model that we can use for future tutorials. I’m calling it widget so it can describe anything generic. This will come in really handy and you will love how easy and intuitive creating a model is in Laravel 5.1*.

Let’s start by going to the command line and running:



php artisan make:model Widget -m

Obviously we are using the make command in artisan and you can see how intuitive this really is. You’ll note that we added the flag -m, so that it will also make a migration for us. This is a super optimized workflow, gotta love that.

In your app folder, you will now see a Widget.php file:



<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Widget extends Model
{
   //
}

And that’s all there is to that!

So let’s go to our migration, which is located in database/migrations, you’ll see something like:



2015_08_171507_create_widgets_table.php

The date time is prepended to the descriptive name of the migration. You should note that Laravel expects a singular name for the model and plural name for the actual DB table.

This is very intuitive because you can think of the model returning a single instance of the tables records, so when we want a widget, we look in the widgets table.

Ok, so with migrations, you a nice stub, ready for you:



use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateWidgetsTable extends Migration
{
   /**
    * Run the migrations.
    *
    * @return void
    */
   public function up()
   {
       Schema::create('widgets', function (Blueprint $table) {
           $table->increments('id');
           $table->timestamps();
       });
   }

   /**
    * Reverse the migrations.
    *
    * @return void
    */
   public function down()
   {
       Schema::drop('widgets');
   }
}

Obviously you are getting the auto-incrementing id column as well as the timestamps, so this is a great timesaver.

So we’re just going to add one column to the up method to keep this simple:



$table->string('widget_name')->unique();

You’ll note that I’m calling it widget_name instead of name. The reason I like to do this is to keep the column name clear. Imagine you have 10 different models, all with a name column. This makes it harder to work with when you are doing joins, so I take the extra step to prepend the modelname_ to the column name. This is not a hard-baked rule, but I like to follow this convention.

Also note, that we put a unique constraint on it. So now your up method should look like this:



public function up()
{
   Schema::create('widgets', function (Blueprint $table) {
       $table->increments('id');
       $table->string('widget_name')->unique();
       $table->timestamps();
   });
}

Now let’s run the migration from the command line:



php artisan migrate

And with that you should have your new table.

Since we’re planning to add records to the widgets table, we need to add the following property to our Widget model:



/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = ['widget_name'];

This tells eloquent that this is a mass assignable property, and if we didn’t have this, Laravel’s Eloquent wouldn’t allow us to save any records.

And that’s all there is to making a model in Laravel. In our next tutorial, we will use Laravel’s model factory to populate some test records. Then, in other tutorials, we will make the routes, controllers and views, so we can play with our widgets.

I hope you have enjoyed this tutorial and found it useful. Click on the sprocket icon at the top of the page to see all tutorials. Please comment, share, and like if you can, thanks.

I don’t have a donate button, but If you would like to support my work and learn more about Laravel, you can do so by buying one of my books, Laraboot: laravel 5* For Beginners, I really appreciate it.