Sunday, April 19, 2015

George's Blog (Software Development): CRUD Operations in Laravel 5 with MYSQL, RESTFUL

George's Blog (Software Development): CRUD Operations in Laravel 5 with MYSQL, RESTFUL: CRUD Operations in Laravel 5 with MYSQL, RESTFUL Here we are to see the changes from laravel 4.3 to laravel 5, At the end of this tutoria...

CRUD Operations in Laravel 5 with MYSQL, RESTFUL

CRUD Operations in Laravel 5 with MYSQL, RESTFUL

Here we are to see the changes from laravel 4.3 to laravel 5, At the end of this tutorial, you should be able to create a basic application in Laravel 5 with MYSQL where you could Create, Read, Update and Delete Books; also we will learn how to use images in our application. We will use RESTFUL for this tutorial.

1. Create bookstore project

Lets create the project called bookstore; for this in the command line type the following command.
 
composer create-project laravel/laravel bookstore --prefer-dist

2. Testing bookstore project

Go to the project folder and execute the following command
 
php artisan serve

Open a web browser and type localhost:8000
bookstore project
Testing bookstore project

Until this point our project is working fine. Otherwise learn how to install Laravel in previous posts.

3. Create database for bookstore

Using your favorite DBMS for MYSQL create a database called library and a table called books with the following fields:
table for bookstore

Please make sure you have exactly these fields in your table, specially update_at and created_at, because Eloquent require them for timestamps.

4. Database setup for bookstore

Here is one of the biggest changes in laravel 5 for security (application and database) Go to bookstore/.env and change the configuration like shown here:

.env file
APP_ENV=local
APP_DEBUG=true
APP_KEY=tqI5Gj43QwYFzSRhHc7JLi57xhixnDYH

DB_HOST=localhost
DB_DATABASE=library
DB_USERNAME=root
DB_PASSWORD=your_mysql_password

CACHE_DRIVER=file
SESSION_DRIVER=file
QUEUE_DRIVER=sync

MAIL_DRIVER=smtp
MAIL_HOST=mailtrap.io
MAIL_PORT=2525
MAIL_USERNAME=null
MAIL_PASSWORD=null

5. Create book controller for bookstore

In the command line locate inside your library project type the following command:
 
php artisan make:controller BookController

Just make sure a new class was created in bookstore/app/Http/Controllers

BookController.php file
<?php namespace App\Http\Controllers;

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

class BookController 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.
    *
    * @return Response
    */
   public function store()
   {
      //
   }
   /**
    * 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  int  $id
    * @return Response
    */
   public function update($id)
   {
      //
   }
   /**
    * Remove the specified resource from storage.
    *
    * @param  int  $id
    * @return Response
    */
   public function destroy($id)
   {
      //
   }
}

6. Create book model

In the command line type the following command:
 
php artisan make:model Book

A new class was created in bookstore/app/ 
Book.php file
<?php namespace App;
use Illuminate\Database\Eloquent\Model;
class Book extends Model {
   //
}

7. Install Form and Html Facades

In order to use Form and Html facades in laravel 5 as they are being removed from core in 5 and will need to be added as an optional dependency: Type the follow command:
 
composer require illuminate/html

After successful installation we will get the following message
 
Using version ~5.0 for illuminate/html
./composer.json has been updated
Loading composer repositories with package information
Updating dependencies (including require-dev)
  - Installing illuminate/html (v5.0.0)
    Loading from cache
Writing lock file
Generating autoload files
Generating optimized class loader
Add in providers config/app.php the following line of code
 
'Illuminate\Html\HtmlServiceProvider',
Add in aliases config/app.php the following lines of code
 
'Form'     => 'Illuminate\Html\FormFacade',
'Html'     => 'Illuminate\Html\HtmlFacade',

8. Restful Controller

In laravel 5, a resource controller defines all the default routes for a given named resource to follow REST principles, where we could find more information about it. So when you define a resource in your bookstore/app/Http/routes.php like:

routes.php file
<?php
/*
|--------------------------------------------------------------------------
| Application Routes
|--------------------------------------------------------------------------
|
| Here is where you can register all of the routes for an application.
| It's a breeze. Simply tell Laravel the URIs it should respond to
| and give it the controller to call when that URI is requested.
|
*/
/*
Route::get('/', 'WelcomeController@index');

Route::get('home', 'HomeController@index');

Route::controllers([
   'auth' => 'Auth\AuthController',
   'password' => 'Auth\PasswordController',
]);*/
Route::resource('books','BookController');

As we can see we block the original code to avoid the default authentication laravel created for us.
A restful controller follows the standard blueprint for a restful resource, which mainly consists of:
Domain Method URI Name Action Midleware

GET|HEAD books books.index App\Http\Controllers\BookController@index

GET|HEAD books/create books.create App\Http\Controllers\BookController@create

POST books books.store App\Http\Controllers\BookController@store

GET|HEAD books/{books} books.show App\Http\Controllers\BookController@show

GET|HEAD books/{books}/edit books.edit App\Http\Controllers\BookController@edit

PUT books/{books} books.update App\Http\Controllers\BookController@update

PATCH books/{books}
App\Http\Controllers\BookController@update

DELETE books/{books} books.destroy App\Http\Controllers\BookController@destroy

To get the table from above; type in the command line:
 
php artisan route:list

9. Insert dummy data

Until this point our project is ready to implement our CRUD operation using Laravel 5 and MySQL, insert some dummy data in the table we created in step 3.

In order to display images for books cover we need to create a folder called img inside bookstore/public and download some books cover picture and rename the name according to the field image in our table as shown above with extension jpg.

10. Create layout for bookstore

Go to folder bookstore/resources/view and create a new folder called layout; inside that new folder create a php file called template.blade.php and copy the following code:

template.blade.php file
 
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>BookStore</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap
/3.3.4/css/bootstrap.min.css">
</head>
<body>
    <div class="container">
        @yield('content')
    </div>
</body>
</html>

11. Create view to show book list

Now let's try to fetch books from our database via the Eloquent object. For this let's modify the index method in our app/Http/Controllers/BookController.php. and modify like show bellow.(note that we added use App\Book, because we need to make reference to Book model)
 
<?php namespace App\Http\Controllers;

use App\Book;
use App\Http\Requests;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;

class BookController extends Controller {

   /**
    * Display a listing of the resource.
    *
    * @return Response
    */
   public function index()
   {
      //
        $books=Book::all();
        return view('books.index',compact('books'));
    }

To display book list we need to create a view: Go to folder bookstore/resources/view and create a folder called books; inside this new folder create a new file called index.blade.php and copy the following code

index..blade.php file
 
@extends('layout/template')

@section('content')
 <h1>Peru BookStore</h1>
 <a href="{{url('/books/create')}}" class="btn btn-success">Create Book</a>
 <hr>
 <table class="table table-striped table-bordered table-hover">
     <thead>
     <tr class="bg-info">
         <th>Id</th>
         <th>ISBN</th>
         <th>Title</th>
         <th>Author</th>
         <th>Publisher</th>
         <th>Thumbs</th>
         <th colspan="3">Actions</th>
     </tr>
     </thead>
     <tbody>
     @foreach ($books as $book)
         <tr>
             <td>{{ $book->id }}</td>
             <td>{{ $book->isbn }}</td>
             <td>{{ $book->title }}</td>
             <td>{{ $book->author }}</td>
             <td>{{ $book->publisher }}</td>
             <td><img src="{{asset('img/'.$book->image.'.jpg')}}" height="35" width="30"></td>
             <td><a href="{{url('books',$book->id)}}" class="btn btn-primary">Read</a></td>
             <td><a href="{{route('books.edit',$book->id)}}" class="btn btn-warning">Update</a></td>
             <td>
             {!! Form::open(['method' => 'DELETE', 'route'=>['books.destroy', $book->id]]) !!}
             {!! Form::submit('Delete', ['class' => 'btn btn-danger']) !!}
             {!! Form::close() !!}
             </td>
         </tr>
     @endforeach

     </tbody>

 </table>
@endsection
Let’s see how our book list are displayed; in the command like type php artisan serve, after open a browser and type localhost:8888/books

12. Read book(Display single book)

Let’s implement Read action, create a new file in bookstore/resources/view/books called show.blade.php and paste the code:

show.blade.php file
@extends('layout/template')
@section('content')
    <h1>Book Show</h1>

    <form class="form-horizontal">
        <div class="form-group">
            <label for="image" class="col-sm-2 control-label">Cover</label>
            <div class="col-sm-10">
                <img src="{{asset('img/'.$book->image.'.jpg')}}" height="180" width="150" class="img-rounded">
            </div>
        </div>
        <div class="form-group">
            <label for="isbn" class="col-sm-2 control-label">ISBN</label>
            <div class="col-sm-10">
                <input type="text" class="form-control" id="isbn" placeholder={{$book->isbn}} readonly>
            </div>
        </div>
        <div class="form-group">
            <label for="title" class="col-sm-2 control-label">Title</label>
            <div class="col-sm-10">
                <input type="text" class="form-control" id="title" placeholder={{$book->title}} readonly>
            </div>
        </div>
        <div class="form-group">
            <label for="author" class="col-sm-2 control-label">Author</label>
            <div class="col-sm-10">
                <input type="text" class="form-control" id="author" placeholder={{$book->author}} readonly>
            </div>
        </div>
        <div class="form-group">
            <label for="publisher" class="col-sm-2 control-label">Publisher</label>
            <div class="col-sm-10">
                <input type="text" class="form-control" id="publisher" placeholder={{$book->publisher}} readonly>
            </div>
        </div>

        <div class="form-group">
            <div class="col-sm-offset-2 col-sm-10">
                <a href="{{ url('books')}}" class="btn btn-primary">Back</a>
            </div>
        </div>
    </form>
@stop
Modify app/Http/Controllers/BookController.php
 
public function show($id)
{
   $book=Book::find($id);
   return view('books.show',compact('book'));
}
Refresh the brower and click in Read action and we will see the book in detail:

13. Create book

Create a new file in bookstore/resources/view/books called create.blade.php and paste the code:

create.blade.php file
 
@extends('layout.template')
@section('content')
    <h1>Create Book</h1>
    {!! Form::open(['url' => 'books']) !!}
    <div class="form-group">
        {!! Form::label('ISBN', 'ISBN:') !!}
        {!! Form::text('isbn',null,['class'=>'form-control']) !!}
    </div>
    <div class="form-group">
        {!! Form::label('Title', 'Title:') !!}
        {!! Form::text('title',null,['class'=>'form-control']) !!}
    </div>
    <div class="form-group">
        {!! Form::label('Author', 'Author:') !!}
        {!! Form::text('author',null,['class'=>'form-control']) !!}
    </div>
    <div class="form-group">
        {!! Form::label('Publisher', 'Publisher:') !!}
        {!! Form::text('publisher',null,['class'=>'form-control']) !!}
    </div>
    <div class="form-group">
        {!! Form::label('Image', 'Image:') !!}
        {!! Form::text('image',null,['class'=>'form-control']) !!}
    </div>
    <div class="form-group">
        {!! Form::submit('Save', ['class' => 'btn btn-primary form-control']) !!}
    </div>
    {!! Form::close() !!}
@stop
Modify app/Http/Controllers/BookController.php
 
public function create()
{
   return view('books.create');
}

/**
 * Store a newly created resource in storage.
 *
 * @return Response
 */
public function store()
{
   $book=Request::all();
   Book::create($book);
   return redirect('books');
}
Now we need to modify the Book model for mass assignment
 
<?php namespace App;
use Illuminate\Database\Eloquent\Model;
class Book extends Model {
   //
    protected $fillable=[
        'isbn',
        'title',
        'author',
        'publisher',
        'image'
    ];
}

refresh the Brower and click on create Book

14. Update Book

Create a new file in bookstore/resources/view/books called edit.blade.php and paste the code:

edit.blade.php file
 
@extends('layout.template')
@section('content')
    <h1>Update Book</h1>
    {!! Form::model($book,['method' => 'PATCH','route'=>['books.update',$book->id]]) !!}
    <div class="form-group">
        {!! Form::label('ISBN', 'ISBN:') !!}
        {!! Form::text('isbn',null,['class'=>'form-control']) !!}
    </div>
    <div class="form-group">
        {!! Form::label('Title', 'Title:') !!}
        {!! Form::text('title',null,['class'=>'form-control']) !!}
    </div>
    <div class="form-group">
        {!! Form::label('Author', 'Author:') !!}
        {!! Form::text('author',null,['class'=>'form-control']) !!}
    </div>
    <div class="form-group">
        {!! Form::label('Publisher', 'Publisher:') !!}
        {!! Form::text('publisher',null,['class'=>'form-control']) !!}
    </div>
    <div class="form-group">
        {!! Form::label('Image', 'Image:') !!}
        {!! Form::text('image',null,['class'=>'form-control']) !!}
    </div>
    <div class="form-group">
        {!! Form::submit('Update', ['class' => 'btn btn-primary']) !!}
    </div>
    {!! Form::close() !!}
@stop
Modify app/Http/Controllers/BookController.php
 
public function edit($id)
{
   $book=Book::find($id);
   return view('books.edit',compact('book'));
}

/**
 * Update the specified resource in storage.
 *
 * @param  int  $id
 * @return Response
 */
public function update($id)
{
   //
   $bookUpdate=Request::all();
   $book=Book::find($id);
   $book->update($bookUpdate);
   return redirect('books');
}
refresh the brower, select the book and click Update button

15. Delete Book

Delete is easy just modify app/Http/Controllers/BookController.php
 
public function destroy($id)
{
   Book::find($id)->delete();
   return redirect('books');
}
Refresh the Brower and click in delete button for deleting one book and redirect to book list.