Larave 6 – CRUD Tutorial With Authentication For Beginners

crud-example-in-laravel-6

In this tutorial, I will show you how to make simple CRUD in laravel 6. CRUD is stand for Create, Read, Update and Delete operation in laravel 6. In the laravel 6 CRUD tutorial, we will create one Todo module for authenticated users. So users can create, read, update and delete there daily todos.

Install Laravel And Database Configuration

Lets install fresh laravel using below artisan command.

composer create-project --prefer-dist laravel/laravel laravel-crud

Now lets create a new lara-crud database and configure database credentials in .env file

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=lara-crud
DB_USERNAME=root
DB_PASSWORD=

So lets get started creating our todo CRUD app in laravel 6 step by step,

Implement Authentication

First of all we are going to make login, registration module for users using laravel authentication.  For authentication we will use inbuilt authentication module of laravel. Laravel makes implementing authentication very simple. In fact, almost everything is configured for you out of the box. Lets make laravel authentication using below artisan command.

Before laravel 6, we can create authentication in laravel using php artisan make:auth artisan command.

But in laravel 6, we need to write some more command. First, we need to install laravel-ui package in development mode. Then we can add boostrap, vue or react using ui command as per our requirement and finally we need to run npm install && npm run dev command.

composer require laravel/ui --dev

php artisan ui bootstrap --auth

npm install && npm run dev

This will install a layout registration and login views, as well as routes for all authentication end-points. It will also use HomeController to handle post-login requests to your application’s dashboard.

We are not going to use HomeController and its default route here, instead we will use our TodoController and set its route for post-login requests. For that we need to do little customization in LoginController and RegistrationController. We will do it later.

Now run artisan migration command which will create required authentication tables in database.

php artisan migrate

Now lets start laravel application server to check authentication functionality using below artisan command.

php artisan serve

This command will start app server on 8000 port. After successfully start server, now navigate this url http://127.0.0.1:8000 in browser. It will show laravel welcome page. You can see login and registration links on welcome page.

I have made some customization on welcome page so my welcome page won’t similar to your welcome page. You can check out my welcome.blade.php page here.

Login : http://127.0.0.1:8000/login

Register : http://127.0.0.1:8000/register

Create Todo Model, Migration & Controller

Now we will create todo model,migration and controller using respective artisan command. Migration will contain database table name and it’s fields. Model will perform operations on database records like store, retrieve, delete and manipulate data etc. Controller will have methods linked with various routes, which we can use to perform various operations.

Create Todo Migration

First of all we need to make a database migration table. Lets make it using below artisan command

php artisan make:migration create_todos_table

This command will generate migration file with default code. Open and update it as below.

<?php

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

class CreateTodosTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('todos', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->string('title');
            $table->string('description');
            $table->integer('user_id');
            $table->enum('status', ['pending','completed']);
            $table->timestamps();
        });
    }

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

Now run below migration command to generate todos database table.

php artisan migrate

Create Todo Model

Now lets create a todo model file using this artisan command.

php artisan make:model Todo

This will generate Todo.php model under app/ directory. We are going to use model file for database logic. Here we have used $fillable property for mass assignable fields.

<?php
# app/Todo.php
namespace App;
use Illuminate\Database\Eloquent\Model;

class Todo extends Model
{
    protected $fillable = ['title', 'description', 'user_id', 'status'];
}

Create Todo Controller

Now its time to create Todo Controller. Controller contain all the CRUD business logic as we need. Lets make it using this artisan command. Here we are using --resource parameter which will generate all resource methods for Create, Read, Update and Delete operations.

php artisan make:controller TodoController --resource

Above artisan command will generate TodoController.php file  under app/Http/Controllers directory. The controller will contain a method for each of the available resource operations. Check below controller default code generated by above artisan controller command.

<?php

# app/Http/Controllers/TodoController.php
namespace App\Http\Controllers;

use Illuminate\Http\Request;

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

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

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

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

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

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

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

Next we need to register resourceful route to access all resource methods from TodoController. Open  routes/web.php file and add route code.

<?php

# routes/web.php
/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/

Route::get('/', function () {
    return view('welcome');
});

Auth::routes();

Route::group(['middleware' => 'auth'], function () {
  Route::resource('/todo', 'TodoController');
});

This single route declaration Route::resource('/todo', 'TodoController'); creates multiple routes to handle a variety of actions on the resource. Here is a list of route which resource route generate.

VerbURIActionRoute Name
GET/todoindextodo.index
GET/todo/createcreatetodo.create
POST/todostoretodo.store
GET/todo/{todo}showtodo.show
GET/todo/{todo}/editedittodo.edit
PUT/PATCH/todo/{todo}updatetodo.update
DELETE/todo/{todo}destroytodo.destroy

Now its time to write code for listing all todos.

Todos Operations

Next lets add various logic to perform various operations in respective resource method.

Todo List

Let’s create a todo list for user. To display todo list we will use index method in TodoController.

TodoController.php

/**
 * Display a listing of the resource.
 *
 * @return \Illuminate\Http\Response
 */
public function index()
{
    $userId = Auth::user()->id;
    $todos = Todo::where(['user_id' => $userId])->get();
    return view('todo.list', ['todos' => $todos]);
}

Here we use where condition on user_id so we can get all todos for particular user. Now lets create list.blade.php layout file under resources/views/todo folder. Add the layout code shown as below.

list.blade.php

# resources/views/todo/list.blade.php
@extends('layouts.app')

@section('content')
<div class="container">
  <br>
    <div class="row justify-content-center">
    	<div class="col-md-6">
    		<h2>Todos List</h2>
    	</div>
    	<div class="col-md-6">
    		<div class="float-right">
    			<a href="{{ route('todo.create') }}" class="btn btn-primary"><i class="fa fa-plus"></i> Add new todo</a>
    		</div>
    	</div>
    	<br>
        <div class="col-md-12">
        	@if (session('success'))
                <div class="alert alert-success" role="alert">
                    {{ session('success') }}
                </div>
            @endif
            @if (session('error'))
                <div class="alert alert-danger" role="alert">
                    {{ session('error') }}
                </div>
            @endif
        	<table class="table table-bordered">
        <thead class="thead-light">
          <tr>
            <th width="5%">#</th>
            <th>Task Name</th>
            <th width="10%"><center>Task Status</center></th>
            <th width="14%"><center>Action</center></th>
          </tr>
        </thead>
        <tbody>
          @forelse ($todos as $todo)
              <tr>
              <th>{{ $todo->id }}</th>
              <td>{{ $todo->title }}</td>
              <td><center>{{ $todo->status }}</center></td>
              <td>
                <div class="action_btn">
                  <div class="action_btn">
                    <a href="{{ route('todo.edit', $todo->id)}}" class="btn btn-warning">Edit</a>
                  </div>
                  <div class="action_btn margin-left-10">
                    <form action="{{ route('todo.destroy', $todo->id)}}" method="post">
                      @csrf
                      @method('DELETE')
                      <button class="btn btn-danger" type="submit">Delete</button>
                    </form>
                  </div>
                </div>
              </td>
            </tr>
          @empty
              <tr>
              <td colspan="4"><center>No data found</center></td>
            </tr>
          @endforelse
        </tbody>
      </table>
        </div>
    </div>
</div>
@endsection

To view all todos listing navigate http://127.0.0.1:8000/todo url and it will show you screen as shown below.

Add/Create Todo

Next we will write code for add todo. We will use two method create and store from TodoController.php for that. Here we will use authenticated user_id to store with todo.

TodoController.php

# app/Http/Controllers/TodoController.php

/**
 * Show the form for creating a new resource.
 *
 * @return \Illuminate\Http\Response
 */
public function create()
{
    return view('todo.add');
}

/**
 * Store a newly created resource in storage.
 *
 * @param  \Illuminate\Http\Request  $request
 * @return \Illuminate\Http\Response
 */
public function store(Request $request)
{
    $userId = Auth::user()->id;
    $input = $request->input();
    $input['user_id'] = $userId;
    $todoStatus = Todo::create($input);
    if ($todoStatus) {
        $request->session()->flash('success', 'Todo successfully added');
    } else {
        $request->session()->flash('error', 'Oops something went wrong, Todo not saved');
    }
    return redirect('todo');
}

We need to create add.blade.php layout file under resources/views/todo folder for rendering add todo form.

add.blade.php [resources/views/todo/add.blade.php]

# resources/views/todo/add.blade.php

@extends('layouts.app')

@section('content')
<div class="container">
  <br>
    <div class="row justify-content-center">
    	<div class="col-md-6">
    		<h2>Add Todo</h2>
    	</div>
    	<div class="col-md-6">
    		<div class="float-right">
    			<a href="{{ route('todo.index') }}" class="btn btn-primary">Back</a>
    		</div>
    	</div>
    	<br>
        <div class="col-md-12">
        	@if (session('success'))
                <div class="alert alert-success" role="alert">
                    {{ session('success') }}
                </div>
            @endif
            @if (session('error'))
                <div class="alert alert-error" role="alert">
                    {{ session('error') }}
                </div>
            @endif
      <form action="{{ route('todo.store') }}" method="POST">
        @csrf
        <div class="form-group">
          <label for="title">Title:</label>
          <input type="text" class="form-control" id="title" name="title">
        </div>
        <div class="form-group">
          <label for="description">Description:</label>
          <textarea name="description" class="form-control" id="description" rows="5"></textarea>
        </div>
        <div class="form-group">
        <label for="status">Select todo status</label>
        <select class="form-control" id="status" name="status">
          <option value="pending">Pending</option>
          <option value="completed">Completed</option>
        </select>
        </div>
        <button type="submit" class="btn btn-default">Submit</button>
      </form>
        </div>
    </div>
</div>
@endsection

You can add new todo using this url http://127.0.0.1/todo/create.

Edit/Update Todo

Next we will add logic for edit/update functionality for existing todo. For that we will use edit and update controller methods. We will also make edit.blade.php view/layout file which contain todo edit form.

TodoController.php

# app/Http/Controllers/TodoController.php

/**
 * Show the form for editing the specified resource.
 *
 * @param  int  $id
 * @return \Illuminate\Http\Response
 */
public function edit($id)
{
    $userId = Auth::user()->id;
    $todo = Todo::where(['user_id' => $userId, 'id' => $id])->first();
    if ($todo) {
        return view('todo.edit', [ 'todo' => $todo ]);
    } else {
        return redirect('todo')->with('error', 'Todo not found');
    }
}

/**
 * Update the specified resource in storage.
 *
 * @param  \Illuminate\Http\Request  $request
 * @param  int  $id
 * @return \Illuminate\Http\Response
 */
public function update(Request $request, $id)
{
    $userId = Auth::user()->id;
    $todo = Todo::find($id);
    if (!$todo) {
        return redirect('todo')->with('error', 'Todo not found.');
    }
    $input = $request->input();
    $input['user_id'] = $userId;
    $todoStatus = $todo->update($input);
    if ($todoStatus) {
        return redirect('todo')->with('success', 'Todo successfully updated.');
    } else {
        return redirect('todo')->with('error', 'Oops something went wrong. Todo not updated');
    }
}

Here edit method will render edit todo form and update method will process form submit data.

resources/views/todo/edit.blade.php

# resources/views/todo/edit.blade.php

@extends('layouts.app')

@section('content')
<div class="container">
  <br>
    <div class="row justify-content-center">
    	<div class="col-md-6">
    		<h2>Edit Todo</h2>
    	</div>
    	<div class="col-md-6">
    		<div class="float-right">
    			<a href="{{ route('todo.index') }}" class="btn btn-primary">Back</a>
    		</div>
    	</div>
    	<br>
        <div class="col-md-12">
        	@if (session('success'))
                <div class="alert alert-success" role="alert">
                    {{ session('success') }}
                </div>
            @endif
            @if (session('error'))
                <div class="alert alert-error" role="alert">
                    {{ session('error') }}
                </div>
            @endif
      <form action="{{ route('todo.update', ['id' => $todo->id]) }}" method="POST">
        @csrf
                @method('PUT')
        <div class="form-group">
          <label for="title">Title:</label>
          <input type="text" class="form-control" id="title" name="title" value="{{ $todo->title }}">
        </div>
        <div class="form-group">
          <label for="description">Description:</label>
          <textarea name="description" class="form-control" id="description" rows="5">{{ $todo->description }}</textarea>
        </div>
        <div class="form-group">
        <label for="status">Select todo status</label>
        <select class="form-control" id="status" name="status">
          <option value="pending" @if ($todo->status == 'pending') selected @endif>Pending</option>
          <option value="completed" @if ($todo->status == 'completed') selected @endif>Completed</option>
        </select>
        </div>
        <button type="submit" class="btn btn-default">Submit</button>
      </form>
        </div>
    </div>
</div>
@endsection

View/Display Todo

To display todo, we will use show method of TodoController.php controller file. Update show() method code as shown below.

TodoController.php

# app/Http/Controllers/TodoController.php

/**
 * Display the specified resource.
 *
 * @param  int  $id
 * @return \Illuminate\Http\Response
 */
public function show($id)
{
    $userId = Auth::user()->id;
    $todo = Todo::where(['user_id' => $userId, 'id' => $id])->first();
    if (!$todo) {
        return redirect('todo')->with('error', 'Todo not found');
    }
    return view('todo.view', ['todo' => $todo]);
}

Now create a view.blade.php layout for display todo.

resources/views/todo/view.blade.php

# resources/views/todo/view.blade.php

@extends('layouts.app')

@section('content')
<div class="container">
  <br>
    <div class="row justify-content-center">
    	<div class="col-md-6">
    		<h2>Todo Details</h2>
    	</div>
    	<div class="col-md-6">
    		<div class="float-right">
    			<a href="{{ route('todo.index') }}" class="btn btn-primary">Back</a>
    		</div>
    	</div>
    	<br>
        <div class="col-md-12">
            <br><br>
        	<div class="todo-title">
                <strong>Title: </strong> {{ $todo->title }}
            </div>
            <br>
            <div class="todo-description">
                <strong>Description: </strong> {{ $todo->description }}
            </div>
            <br>
            <div class="todo-description">
                <strong>Status: </strong> {{ $todo->status }}
            </div>
        </div>
    </div>
</div>
@endsection

Destroy Todo

We will use destroy method of TodoController file to destroy/delete todo. We don’t need any layout file for destroy operation. Here we will only notify user about destroy operation and redirect to todo list route.

# app/Http/Controllers/TodoController.php

/**
 * Remove the specified resource from storage.
 *
 * @param  int  $id
 * @return \Illuminate\Http\Response
 */
public function destroy($id)
{
    $userId = Auth::user()->id;
    $todo = Todo::where(['user_id' => $userId, 'id' => $id])->first();
    $respStatus = $respMsg = '';
    if (!$todo) {
        $respStatus = 'error';
        $respMsg = 'Todo not found';
    }
    $todoDelStatus = $todo->delete();
    if ($todoDelStatus) {
        $respStatus = 'success';
        $respMsg = 'Todo deleted successfully';
    } else {
        $respStatus = 'error';
        $respMsg = 'Oops something went wrong. Todo not deleted successfully';
    }
    return redirect('todo')->with($respStatus, $respMsg);
}

Update Auth Redirect Routes

Now we will update post-login request route  in LoginController and RegistrationController as below.

LoginController.php [app/Http/Controllers/Auth]

/**
 * Where to redirect users after login.
 *
 * @var string
 */
protected $redirectTo = '/todo';

RegisterController.php [app/Http/Controllers/Auth]

/**
 * Where to redirect users after registration.
 *
 * @var string
 */
protected $redirectTo = '/todo';

The reason behind updating this route is that it will redirect to todo list page after successful registration and login of user. Normally it redirect to dashboard page of HomeController but we dont need it so we use different route.

I hope that you may like this CRUD tutorial in laravel 6. Please share with your friends as well. You can download code from github repository and setup it in your system. There is project setup guide available in README.md file. If you need any help, please write it in comment. I will try to help you.

About Chintan Panchal

I am web developer having 4+ year of experience of web development. I have worked on codeigniter, symfony, laravel and wordpress.

View all posts by Chintan Panchal →

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.