In this tutorial, we will explore how to implement user roles and permissions in Laravel, a popular PHP framework. Managing user roles and permissions is crucial for applications with varying levels of access and functionality. We’ll cover everything from setting up roles and permissions to implementing authorization checks in your Laravel application.

Before we dive into CRUD tutorial, I assuming you have the following installed on your system:

  • Composer (Dependency Manager for PHP)
  • PHP
  • MySQL (or any other database of your choice)
  • Basic understanding of PHP and MVC architecture

Laravel  Project Setup

Create Laravel project with the following command using composer:

composer create-project laravel/laravel permission-app
cd permission-app

Database Setup

Set up your database configuration in .env file and migrate the necessary tables:

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=permissiontutorial
DB_USERNAME=root
DB_PASSWORD=

Install Packages

we will install Spatie package for ACL(Access Control List) in our projects , that way we can use it’s method. Also we will install form collection package. So Open your terminal and run bellow both commands.

composer require spatie/laravel-permission
composer require laravelcollective/html
composer require laravel/ui

After installing the package, open your config/app.php file and add the service provider and alias:

'providers' => [
    // Other Service Providers
    Spatie\Permission\PermissionServiceProvider::class,
],

'aliases' => [
    // Other Aliases
    'Permission' => Spatie\Permission\Models\Permission::class,
],

Publish Configuration and Migration Files

To customize the package or make changes, publish the configuration and migration files provided by Spatie. This will allow you to modify settings and adjust the database structure if needed.

Run the following artisan command:

php artisan vendor:publish --provider="Spatie\Permission\PermissionServiceProvider"

This command will create a config/permission.php file where you can configure the package. and it will also publish migration files to create necessary database tables.

After publishing the migration files, migrate the database to create the required tables:

php artisan migrate

Create Product Migration

In this step we have to create product tables this tutorial but we generate with using model command with -m options

Product Table

    php artisan make:model Product -m

    Product migration file

    <?php
    
    
    use Illuminate\Support\Facades\Schema;
    use Illuminate\Database\Schema\Blueprint;
    use Illuminate\Database\Migrations\Migration;
    
    
    class CreateProductsTable extends Migration
    {
        /**
         * Run the migrations.
         *
         * @return void
         */
        public function up()
        {
            Schema::create('products', function (Blueprint $table) {
                $table->id();
                $table->string('name');
                $table->text('detail');
                $table->timestamps();
            });
        }
    
    
        /**
         * Reverse the migrations.
         *
         * @return void
         */
        public function down()
        {
            Schema::dropIfExists('products');
        }
    }

    app/Models/Product.php

    <?php
      
    namespace App\Models;
      
    use Illuminate\Database\Eloquent\Factories\HasFactory;
    use Illuminate\Database\Eloquent\Model;
      
    class Product extends Model
    {
        use HasFactory;
      
        /**
         * The attributes that are mass assignable.
         *	
         * @var array
         */
        protected $fillable = [
            'name', 'detail'
        ];
    }

    Modify Pre Generated User Model

    app/Models/User.php

    <?php
      
    namespace App\Models;
      
    use Illuminate\Contracts\Auth\MustVerifyEmail;
    use Illuminate\Database\Eloquent\Factories\HasFactory;
    use Illuminate\Foundation\Auth\User as Authenticatable;
    use Illuminate\Notifications\Notifiable;
    use Spatie\Permission\Traits\HasRoles;
      
    class User extends Authenticatable
    {
        use HasFactory, Notifiable, HasRoles;
      
        /**
         * The attributes that are mass assignable.
         *
         * @var array
         */
        protected $fillable = [
            'name',
            'email',
            'password',
        ];
      
        /**
         * The attributes that should be hidden for arrays.
         *
         * @var array
         */
        protected $hidden = [
            'password',
            'remember_token',
        ];
      
        /**
         * The attributes that should be cast to native types.
         *
         * @var array
         */
        protected $casts = [
            'email_verified_at' => 'datetime',
        ];
    }

    Add Middleware

    Don’t worry we will not create any middleware because spatie provide us in-built middleware we can use it simply and that is display as bellow

    1. Role
    2. Permission

    So, we have to add middleware in Kernel.php file this way

    app/Http/Kernel.php

    protected $routeMiddleware = [
        ....
        'role' => \Spatie\Permission\Middlewares\RoleMiddleware::class,
        'permission' => \Spatie\Permission\Middlewares\PermissionMiddleware::class,
        'role_or_permission' => \Spatie\Permission\Middlewares\RoleOrPermissionMiddleware::class,
    ]

    Authentications

    You have to follow few more steps to make auth in your Laravel application. This is command only steps.

    First you need to install laravel/ui package as like bellow:

    composer require laravel/ui

    Here, we need to generate auth scaffolding in laravel 8 using laravel ui command. so, let’s generate it by bellow command:

    php artisan ui bootstrap --auth

    Now you need to run npm command, otherwise you will see blank pages or occur any error .

    Install NPM

    npm install

    Run NPM

    npm run dev

    Routes Setup

    We require to add number of route for users module, products module and roles module. In this this route i also use middleware with permission for roles and products route, so add route this way:

    routes/web.php

    <?php
      
    use Illuminate\Support\Facades\Route;
      
    use App\Http\Controllers\HomeController;
    use App\Http\Controllers\RoleController;
    use App\Http\Controllers\UserController;
    use App\Http\Controllers\ProductController;
      
    /*
    |--------------------------------------------------------------------------
    | 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::get('/home', [HomeController::class, 'index'])->name('home');
      
    Route::group(['middleware' => ['auth']], function() {
        Route::resource('roles', RoleController::class);
        Route::resource('users', UserController::class);
        Route::resource('products', ProductController::class);
    });

    Controller Setup

    In this step we have add controllers for users module, products module and roles module so we will create all controller for these modules

    app/Http/Controllers/UserController.php

    <?php
        
    namespace App\Http\Controllers;
        
    use Illuminate\Http\Request;
    use App\Http\Controllers\Controller;
    use App\Models\User;
    use Spatie\Permission\Models\Role;
    use DB;
    use Hash;
    use Illuminate\Support\Arr;
        
    class UserController extends Controller
    {
        /**
         * Display a listing of the resource.
         *
         * @return \Illuminate\Http\Response
         */
        public function index(Request $request)
        {
            $data = User::orderBy('id','DESC')->paginate(5);
            return view('users.index',compact('data'))
                ->with('i', ($request->input('page', 1) - 1) * 5);
        }
        
        /**
         * Show the form for creating a new resource.
         *
         * @return \Illuminate\Http\Response
         */
        public function create()
        {
            $roles = Role::pluck('name','name')->all();
            return view('users.create',compact('roles'));
        }
        
        /**
         * Store a newly created resource in storage.
         *
         * @param  \Illuminate\Http\Request  $request
         * @return \Illuminate\Http\Response
         */
        public function store(Request $request)
        {
            $this->validate($request, [
                'name' => 'required',
                'email' => 'required|email|unique:users,email',
                'password' => 'required|same:confirm-password',
                'roles' => 'required'
            ]);
        
            $input = $request->all();
            $input['password'] = Hash::make($input['password']);
        
            $user = User::create($input);
            $user->assignRole($request->input('roles'));
        
            return redirect()->route('users.index')
                            ->with('success','User created successfully');
        }
        
        /**
         * Display the specified resource.
         *
         * @param  int  $id
         * @return \Illuminate\Http\Response
         */
        public function show($id)
        {
            $user = User::find($id);
            return view('users.show',compact('user'));
        }
        
        /**
         * Show the form for editing the specified resource.
         *
         * @param  int  $id
         * @return \Illuminate\Http\Response
         */
        public function edit($id)
        {
            $user = User::find($id);
            $roles = Role::pluck('name','name')->all();
            $userRole = $user->roles->pluck('name','name')->all();
        
            return view('users.edit',compact('user','roles','userRole'));
        }
        
        /**
         * Update the specified resource in storage.
         *
         * @param  \Illuminate\Http\Request  $request
         * @param  int  $id
         * @return \Illuminate\Http\Response
         */
        public function update(Request $request, $id)
        {
            $this->validate($request, [
                'name' => 'required',
                'email' => 'required|email|unique:users,email,'.$id,
                'password' => 'same:confirm-password',
                'roles' => 'required'
            ]);
        
            $input = $request->all();
            if(!empty($input['password'])){ 
                $input['password'] = Hash::make($input['password']);
            }else{
                $input = Arr::except($input,array('password'));    
            }
        
            $user = User::find($id);
            $user->update($input);
            DB::table('model_has_roles')->where('model_id',$id)->delete();
        
            $user->assignRole($request->input('roles'));
        
            return redirect()->route('users.index')
                            ->with('success','User updated successfully');
        }
        
        /**
         * Remove the specified resource from storage.
         *
         * @param  int  $id
         * @return \Illuminate\Http\Response
         */
        public function destroy($id)
        {
            User::find($id)->delete();
            return redirect()->route('users.index')
                            ->with('success','User deleted successfully');
        }
    }

    We Generate Product Controller using below command

    php artisan make:controller ProductController -r

    app/Http/Controllers/ProductController.php

    <?php
        
    namespace App\Http\Controllers;
        
    use App\Models\Product;
    use Illuminate\Http\Request;
        
    class ProductController extends Controller
    { 
        /**
         * Display a listing of the resource.
         *
         * @return \Illuminate\Http\Response
         */
        function __construct()
        {
             $this->middleware('permission:product-list|product-create|product-edit|product-delete', ['only' => ['index','show']]);
             $this->middleware('permission:product-create', ['only' => ['create','store']]);
             $this->middleware('permission:product-edit', ['only' => ['edit','update']]);
             $this->middleware('permission:product-delete', ['only' => ['destroy']]);
        }
        /**
         * Display a listing of the resource.
         *
         * @return \Illuminate\Http\Response
         */
        public function index()
        {
            $products = Product::latest()->paginate(5);
            return view('products.index',compact('products'))
                ->with('i', (request()->input('page', 1) - 1) * 5);
        }
        
        /**
         * Show the form for creating a new resource.
         *
         * @return \Illuminate\Http\Response
         */
        public function create()
        {
            return view('products.create');
        }
        
        /**
         * Store a newly created resource in storage.
         *
         * @param  \Illuminate\Http\Request  $request
         * @return \Illuminate\Http\Response
         */
        public function store(Request $request)
        {
            request()->validate([
                'name' => 'required',
                'detail' => 'required',
            ]);
        
            Product::create($request->all());
        
            return redirect()->route('products.index')
                            ->with('success','Product created successfully.');
        }
        
        /**
         * Display the specified resource.
         *
         * @param  \App\Product  $product
         * @return \Illuminate\Http\Response
         */
        public function show(Product $product)
        {
            return view('products.show',compact('product'));
        }
        
        /**
         * Show the form for editing the specified resource.
         *
         * @param  \App\Product  $product
         * @return \Illuminate\Http\Response
         */
        public function edit(Product $product)
        {
            return view('products.edit',compact('product'));
        }
        
        /**
         * Update the specified resource in storage.
         *
         * @param  \Illuminate\Http\Request  $request
         * @param  \App\Product  $product
         * @return \Illuminate\Http\Response
         */
        public function update(Request $request, Product $product)
        {
             request()->validate([
                'name' => 'required',
                'detail' => 'required',
            ]);
        
            $product->update($request->all());
        
            return redirect()->route('products.index')
                            ->with('success','Product updated successfully');
        }
        
        /**
         * Remove the specified resource from storage.
         *
         * @param  \App\Product  $product
         * @return \Illuminate\Http\Response
         */
        public function destroy(Product $product)
        {
            $product->delete();
        
            return redirect()->route('products.index')
                            ->with('success','Product deleted successfully');
        }
    }

    We Generate Role Controller using below command

    php artisan make:controller RoleController -r

    app/Http/Controllers/RoleController.php

    <?php
        
    namespace App\Http\Controllers;
    
    
    use Illuminate\Http\Request;
    use App\Http\Controllers\Controller;
    use Spatie\Permission\Models\Role;
    use Spatie\Permission\Models\Permission;
    use DB;
        
    class RoleController extends Controller
    {
        /**
         * Display a listing of the resource.
         *
         * @return \Illuminate\Http\Response
         */
        function __construct()
        {
             $this->middleware('permission:role-list|role-create|role-edit|role-delete', ['only' => ['index','store']]);
             $this->middleware('permission:role-create', ['only' => ['create','store']]);
             $this->middleware('permission:role-edit', ['only' => ['edit','update']]);
             $this->middleware('permission:role-delete', ['only' => ['destroy']]);
        }
        
        /**
         * Display a listing of the resource.
         *
         * @return \Illuminate\Http\Response
         */
        public function index(Request $request)
        {
            $roles = Role::orderBy('id','DESC')->paginate(5);
            return view('roles.index',compact('roles'))
                ->with('i', ($request->input('page', 1) - 1) * 5);
        }
        
        /**
         * Show the form for creating a new resource.
         *
         * @return \Illuminate\Http\Response
         */
        public function create()
        {
            $permission = Permission::get();
            return view('roles.create',compact('permission'));
        }
        
        /**
         * Store a newly created resource in storage.
         *
         * @param  \Illuminate\Http\Request  $request
         * @return \Illuminate\Http\Response
         */
        public function store(Request $request)
        {
            $this->validate($request, [
                'name' => 'required|unique:roles,name',
                'permission' => 'required',
            ]);
        
            $role = Role::create(['name' => $request->input('name')]);
            $role->syncPermissions($request->input('permission'));
        
            return redirect()->route('roles.index')
                            ->with('success','Role created successfully');
        }
        /**
         * Display the specified resource.
         *
         * @param  int  $id
         * @return \Illuminate\Http\Response
         */
        public function show($id)
        {
            $role = Role::find($id);
            $rolePermissions = Permission::join("role_has_permissions","role_has_permissions.permission_id","=","permissions.id")
                ->where("role_has_permissions.role_id",$id)
                ->get();
        
            return view('roles.show',compact('role','rolePermissions'));
        }
        
        /**
         * Show the form for editing the specified resource.
         *
         * @param  int  $id
         * @return \Illuminate\Http\Response
         */
        public function edit($id)
        {
            $role = Role::find($id);
            $permission = Permission::get();
            $rolePermissions = DB::table("role_has_permissions")->where("role_has_permissions.role_id",$id)
                ->pluck('role_has_permissions.permission_id','role_has_permissions.permission_id')
                ->all();
        
            return view('roles.edit',compact('role','permission','rolePermissions'));
        }
        
        /**
         * Update the specified resource in storage.
         *
         * @param  \Illuminate\Http\Request  $request
         * @param  int  $id
         * @return \Illuminate\Http\Response
         */
        public function update(Request $request, $id)
        {
            $this->validate($request, [
                'name' => 'required',
                'permission' => 'required',
            ]);
        
            $role = Role::find($id);
            $role->name = $request->input('name');
            $role->save();
        
            $role->syncPermissions($request->input('permission'));
        
            return redirect()->route('roles.index')
                            ->with('success','Role updated successfully');
        }
        /**
         * Remove the specified resource from storage.
         *
         * @param  int  $id
         * @return \Illuminate\Http\Response
         */
        public function destroy($id)
        {
            DB::table("roles")->where('id',$id)->delete();
            return redirect()->route('roles.index')
                            ->with('success','Role deleted successfully');
        }
    }

    Views Setup

    In this step, we will create frontend part of this tutorial

    Layout file (resources/views/layouts )

    1. app.blade.php

    User Module (resources/views/users)

    1. index.blade.php
    2. create.blade.php
    3. edit.blade.php
    4. show.blade.php

    Roles Module (resources/views/roles)

    1. index.blade.php
    2. create.blade.php
    3. edit.blade.php
    4. show.blade.php

    Products Module (resources/views/product)

    1. index.blade.php
    2. create.blade.php
    3. edit.blade.php
    4. show.blade.php

    resources/views/layouts/app.blade.php

    <html lang="{{ app()->getLocale() }}">
    <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <!-- CSRF Token -->
        <meta name="csrf-token" content="{{ csrf_token() }}">
        <title>{{ config('app.name', 'Laravel User Roles and Permissions Tutorial') }}</title>
        <!-- Scripts -->
        <script src="{{ asset('js/app.js') }}" defer></script>
        <!-- Fonts -->
        <link rel="dns-prefetch" href="https://fonts.gstatic.com">
        <link href="https://fonts.googleapis.com/css?family=Raleway:300,400,600" rel="stylesheet" type="text/css">
        <!-- Styles -->
        <link href="{{ asset('css/app.css') }}" rel="stylesheet">
    </head>
    <body>
        <div id="app">
            <nav class="navbar navbar-expand-md navbar-light navbar-laravel">
                <div class="container">
                    <a class="navbar-brand" href="{{ url('/') }}">
                        Laravel User Roles and Permissions
                    </a>
                    <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
                        <span class="navbar-toggler-icon"></span>
                    </button>
        
                    <div class="collapse navbar-collapse" id="navbarSupportedContent">
                        <!-- Left Side Of Navbar -->
                        <ul class="navbar-nav mr-auto"></ul>
    
    
                        <!-- Right Side Of Navbar -->
                        <ul class="navbar-nav ml-auto">
                            <!-- Authentication Links -->
                            @guest
                                <li><a class="nav-link" href="{{ route('login') }}">{{ __('Login') }}</a></li>
                                <li><a class="nav-link" href="{{ route('register') }}">{{ __('Register') }}</a></li>
                            @else
                                <li><a class="nav-link" href="{{ route('users.index') }}">Manage Users</a></li>
                                <li><a class="nav-link" href="{{ route('roles.index') }}">Manage Role</a></li>
                                <li><a class="nav-link" href="{{ route('products.index') }}">Manage Product</a></li>
                                <li class="nav-item dropdown">
                                    <a id="navbarDropdown" class="nav-link dropdown-toggle" href="#" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" v-pre>
                                        {{ Auth::user()->name }} <span class="caret"></span>
                                    </a>
    
    
                                    <div class="dropdown-menu" aria-labelledby="navbarDropdown">
                                        <a class="dropdown-item" href="{{ route('logout') }}"
                                           onclick="event.preventDefault();
                                                         document.getElementById('logout-form').submit();">
                                            {{ __('Logout') }}
                                        </a>
    
    
                                        <form id="logout-form" action="{{ route('logout') }}" method="POST" style="display: none;">
                                            @csrf
                                        </form>
                                    </div>
                                </li>
                            @endguest
                        </ul>
                    </div>
                </div>
            </nav>
    
    
            <main class="py-4">
                <div class="container">
                @yield('content')
                </div>
            </main>
        </div>
    </body>
    </html>

    resources/views/users/index.blade.php

    @extends('layouts.app')
    
    
    @section('content')
    <div class="row">
        <div class="col-lg-12 margin-tb">
            <div class="pull-left">
                <h2>Users Management</h2>
            </div>
            <div class="pull-right">
                <a class="btn btn-success" href="{{ route('users.create') }}"> Create New User</a>
            </div>
        </div>
    </div>
    
    
    @if ($message = Session::get('success'))
    <div class="alert alert-success">
      <p>{{ $message }}</p>
    </div>
    @endif
    
    
    <table class="table table-bordered">
     <tr>
       <th>No</th>
       <th>Name</th>
       <th>Email</th>
       <th>Roles</th>
       <th width="280px">Action</th>
     </tr>
     @foreach ($data as $key => $user)
      <tr>
        <td>{{ ++$i }}</td>
        <td>{{ $user->name }}</td>
        <td>{{ $user->email }}</td>
        <td>
          @if(!empty($user->getRoleNames()))
            @foreach($user->getRoleNames() as $v)
               <label class="badge badge-success">{{ $v }}</label>
            @endforeach
          @endif
        </td>
        <td>
           <a class="btn btn-info" href="{{ route('users.show',$user->id) }}">Show</a>
           <a class="btn btn-primary" href="{{ route('users.edit',$user->id) }}">Edit</a>
            {!! Form::open(['method' => 'DELETE','route' => ['users.destroy', $user->id],'style'=>'display:inline']) !!}
                {!! Form::submit('Delete', ['class' => 'btn btn-danger']) !!}
            {!! Form::close() !!}
        </td>
      </tr>
     @endforeach
    </table>
    
    
    {!! $data->render() !!}
    
    
    
    @endsection

    resources/views/users/create.blade.php

    @extends('layouts.app')
    
    
    @section('content')
    <div class="row">
        <div class="col-lg-12 margin-tb">
            <div class="pull-left">
                <h2>Create New User</h2>
            </div>
            <div class="pull-right">
                <a class="btn btn-primary" href="{{ route('users.index') }}"> Back</a>
            </div>
        </div>
    </div>
    
    
    @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
    
    
    
    {!! Form::open(array('route' => 'users.store','method'=>'POST')) !!}
    <div class="row">
        <div class="col-xs-12 col-sm-12 col-md-12">
            <div class="form-group">
                <strong>Name:</strong>
                {!! Form::text('name', null, array('placeholder' => 'Name','class' => 'form-control')) !!}
            </div>
        </div>
        <div class="col-xs-12 col-sm-12 col-md-12">
            <div class="form-group">
                <strong>Email:</strong>
                {!! Form::text('email', null, array('placeholder' => 'Email','class' => 'form-control')) !!}
            </div>
        </div>
        <div class="col-xs-12 col-sm-12 col-md-12">
            <div class="form-group">
                <strong>Password:</strong>
                {!! Form::password('password', array('placeholder' => 'Password','class' => 'form-control')) !!}
            </div>
        </div>
        <div class="col-xs-12 col-sm-12 col-md-12">
            <div class="form-group">
                <strong>Confirm Password:</strong>
                {!! Form::password('confirm-password', array('placeholder' => 'Confirm Password','class' => 'form-control')) !!}
            </div>
        </div>
        <div class="col-xs-12 col-sm-12 col-md-12">
            <div class="form-group">
                <strong>Role:</strong>
                {!! Form::select('roles[]', $roles,[], array('class' => 'form-control','multiple')) !!}
            </div>
        </div>
        <div class="col-xs-12 col-sm-12 col-md-12 text-center">
            <button type="submit" class="btn btn-primary">Submit</button>
        </div>
    </div>
    {!! Form::close() !!}
    
    
    
    @endsection

    resources/views/users/edit.blade.php

    @extends('layouts.app')
    
    
    @section('content')
    <div class="row">
        <div class="col-lg-12 margin-tb">
            <div class="pull-left">
                <h2>Edit New User</h2>
            </div>
            <div class="pull-right">
                <a class="btn btn-primary" href="{{ route('users.index') }}"> Back</a>
            </div>
        </div>
    </div>
    
    
    @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
    
    
    {!! Form::model($user, ['method' => 'PATCH','route' => ['users.update', $user->id]]) !!}
    <div class="row">
        <div class="col-xs-12 col-sm-12 col-md-12">
            <div class="form-group">
                <strong>Name:</strong>
                {!! Form::text('name', null, array('placeholder' => 'Name','class' => 'form-control')) !!}
            </div>
        </div>
        <div class="col-xs-12 col-sm-12 col-md-12">
            <div class="form-group">
                <strong>Email:</strong>
                {!! Form::text('email', null, array('placeholder' => 'Email','class' => 'form-control')) !!}
            </div>
        </div>
        <div class="col-xs-12 col-sm-12 col-md-12">
            <div class="form-group">
                <strong>Password:</strong>
                {!! Form::password('password', array('placeholder' => 'Password','class' => 'form-control')) !!}
            </div>
        </div>
        <div class="col-xs-12 col-sm-12 col-md-12">
            <div class="form-group">
                <strong>Confirm Password:</strong>
                {!! Form::password('confirm-password', array('placeholder' => 'Confirm Password','class' => 'form-control')) !!}
            </div>
        </div>
        <div class="col-xs-12 col-sm-12 col-md-12">
            <div class="form-group">
                <strong>Role:</strong>
                {!! Form::select('roles[]', $roles,$userRole, array('class' => 'form-control','multiple')) !!}
            </div>
        </div>
        <div class="col-xs-12 col-sm-12 col-md-12 text-center">
            <button type="submit" class="btn btn-primary">Submit</button>
        </div>
    </div>
    {!! Form::close() !!}
    
    
    
    @endsection

    resources/views/users/show.blade.php

    @extends('layouts.app')
    
    
    @section('content')
    <div class="row">
        <div class="col-lg-12 margin-tb">
            <div class="pull-left">
                <h2> Show User</h2>
            </div>
            <div class="pull-right">
                <a class="btn btn-primary" href="{{ route('users.index') }}"> Back</a>
            </div>
        </div>
    </div>
    
    
    <div class="row">
        <div class="col-xs-12 col-sm-12 col-md-12">
            <div class="form-group">
                <strong>Name:</strong>
                {{ $user->name }}
            </div>
        </div>
        <div class="col-xs-12 col-sm-12 col-md-12">
            <div class="form-group">
                <strong>Email:</strong>
                {{ $user->email }}
            </div>
        </div>
        <div class="col-xs-12 col-sm-12 col-md-12">
            <div class="form-group">
                <strong>Roles:</strong>
                @if(!empty($user->getRoleNames()))
                    @foreach($user->getRoleNames() as $v)
                        <label class="badge badge-success">{{ $v }}</label>
                    @endforeach
                @endif
            </div>
        </div>
    </div>
    @endsection

    resources/views/roles/index.blade.php

    @extends('layouts.app')
    
    
    @section('content')
    <div class="row">
        <div class="col-lg-12 margin-tb">
            <div class="pull-left">
                <h2>Role Management</h2>
            </div>
            <div class="pull-right">
            @can('role-create')
                <a class="btn btn-success" href="{{ route('roles.create') }}"> Create New Role</a>
                @endcan
            </div>
        </div>
    </div>
    
    
    @if ($message = Session::get('success'))
        <div class="alert alert-success">
            <p>{{ $message }}</p>
        </div>
    @endif
    
    
    <table class="table table-bordered">
      <tr>
         <th>No</th>
         <th>Name</th>
         <th width="280px">Action</th>
      </tr>
        @foreach ($roles as $key => $role)
        <tr>
            <td>{{ ++$i }}</td>
            <td>{{ $role->name }}</td>
            <td>
                <a class="btn btn-info" href="{{ route('roles.show',$role->id) }}">Show</a>
                @can('role-edit')
                    <a class="btn btn-primary" href="{{ route('roles.edit',$role->id) }}">Edit</a>
                @endcan
                @can('role-delete')
                    {!! Form::open(['method' => 'DELETE','route' => ['roles.destroy', $role->id],'style'=>'display:inline']) !!}
                        {!! Form::submit('Delete', ['class' => 'btn btn-danger']) !!}
                    {!! Form::close() !!}
                @endcan
            </td>
        </tr>
        @endforeach
    </table>
    
    
    {!! $roles->render() !!}
    
    
    @endsection

    resources/views/roles/create.blade.php

    @extends('layouts.app')
    
    
    @section('content')
    <div class="row">
        <div class="col-lg-12 margin-tb">
            <div class="pull-left">
                <h2>Create New Role</h2>
            </div>
            <div class="pull-right">
                <a class="btn btn-primary" href="{{ route('roles.index') }}"> Back</a>
            </div>
        </div>
    </div>
    
    
    @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
    
    
    {!! Form::open(array('route' => 'roles.store','method'=>'POST')) !!}
    <div class="row">
        <div class="col-xs-12 col-sm-12 col-md-12">
            <div class="form-group">
                <strong>Name:</strong>
                {!! Form::text('name', null, array('placeholder' => 'Name','class' => 'form-control')) !!}
            </div>
        </div>
        <div class="col-xs-12 col-sm-12 col-md-12">
            <div class="form-group">
                <strong>Permission:</strong>
                <br/>
                @foreach($permission as $value)
                    <label>{{ Form::checkbox('permission[]', $value->id, false, array('class' => 'name')) }}
                    {{ $value->name }}</label>
                <br/>
                @endforeach
            </div>
        </div>
        <div class="col-xs-12 col-sm-12 col-md-12 text-center">
            <button type="submit" class="btn btn-primary">Submit</button>
        </div>
    </div>
    {!! Form::close() !!}
    
    
    
    @endsection

    resources/views/roles/edit.blade.php

    @extends('layouts.app')
    
    
    @section('content')
    <div class="row">
        <div class="col-lg-12 margin-tb">
            <div class="pull-left">
                <h2>Edit Role</h2>
            </div>
            <div class="pull-right">
                <a class="btn btn-primary" href="{{ route('roles.index') }}"> Back</a>
            </div>
        </div>
    </div>
    
    
    @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
    
    
    {!! Form::model($role, ['method' => 'PATCH','route' => ['roles.update', $role->id]]) !!}
    <div class="row">
        <div class="col-xs-12 col-sm-12 col-md-12">
            <div class="form-group">
                <strong>Name:</strong>
                {!! Form::text('name', null, array('placeholder' => 'Name','class' => 'form-control')) !!}
            </div>
        </div>
        <div class="col-xs-12 col-sm-12 col-md-12">
            <div class="form-group">
                <strong>Permission:</strong>
                <br/>
                @foreach($permission as $value)
                    <label>{{ Form::checkbox('permission[]', $value->id, in_array($value->id, $rolePermissions) ? true : false, array('class' => 'name')) }}
                    {{ $value->name }}</label>
                <br/>
                @endforeach
            </div>
        </div>
        <div class="col-xs-12 col-sm-12 col-md-12 text-center">
            <button type="submit" class="btn btn-primary">Submit</button>
        </div>
    </div>
    {!! Form::close() !!}
    
    
    @endsection
    
    

    resources/views/roles/show.blade.php

    @extends('layouts.app')
    
    
    @section('content')
    <div class="row">
        <div class="col-lg-12 margin-tb">
            <div class="pull-left">
                <h2> Show Role</h2>
            </div>
            <div class="pull-right">
                <a class="btn btn-primary" href="{{ route('roles.index') }}"> Back</a>
            </div>
        </div>
    </div>
    
    
    <div class="row">
        <div class="col-xs-12 col-sm-12 col-md-12">
            <div class="form-group">
                <strong>Name:</strong>
                {{ $role->name }}
            </div>
        </div>
        <div class="col-xs-12 col-sm-12 col-md-12">
            <div class="form-group">
                <strong>Permissions:</strong>
                @if(!empty($rolePermissions))
                    @foreach($rolePermissions as $v)
                        <label class="label label-success">{{ $v->name }},</label>
                    @endforeach
                @endif
            </div>
        </div>
    </div>
    @endsection

    resources/views/products/index.blade.php

    @extends('layouts.app')
    
    
    @section('content')
        <div class="row">
            <div class="col-lg-12 margin-tb">
                <div class="pull-left">
                    <h2>Products</h2>
                </div>
                <div class="pull-right">
                    @can('product-create')
                    <a class="btn btn-success" href="{{ route('products.create') }}"> Create New Product</a>
                    @endcan
                </div>
            </div>
        </div>
    
    
        @if ($message = Session::get('success'))
            <div class="alert alert-success">
                <p>{{ $message }}</p>
            </div>
        @endif
    
    
        <table class="table table-bordered">
            <tr>
                <th>No</th>
                <th>Name</th>
                <th>Details</th>
                <th width="280px">Action</th>
            </tr>
    	    @foreach ($products as $product)
    	    <tr>
    	        <td>{{ ++$i }}</td>
    	        <td>{{ $product->name }}</td>
    	        <td>{{ $product->detail }}</td>
    	        <td>
                    <form action="{{ route('products.destroy',$product->id) }}" method="POST">
                        <a class="btn btn-info" href="{{ route('products.show',$product->id) }}">Show</a>
                        @can('product-edit')
                        <a class="btn btn-primary" href="{{ route('products.edit',$product->id) }}">Edit</a>
                        @endcan
    
    
                        @csrf
                        @method('DELETE')
                        @can('product-delete')
                        <button type="submit" class="btn btn-danger">Delete</button>
                        @endcan
                    </form>
    	        </td>
    	    </tr>
    	    @endforeach
        </table>
    
    
        {!! $products->links() !!}
    
    
    
    @endsection

    resources/views/products/create.blade.php

    @extends('layouts.app')
    
    
    @section('content')
        <div class="row">
            <div class="col-lg-12 margin-tb">
                <div class="pull-left">
                    <h2>Add New Product</h2>
                </div>
                <div class="pull-right">
                    <a class="btn btn-primary" href="{{ route('products.index') }}"> Back</a>
                </div>
            </div>
        </div>
    
    
        @if ($errors->any())
            <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
    
    
        <form action="{{ route('products.store') }}" method="POST">
        	@csrf
    
    
             <div class="row">
    		    <div class="col-xs-12 col-sm-12 col-md-12">
    		        <div class="form-group">
    		            <strong>Name:</strong>
    		            <input type="text" name="name" class="form-control" placeholder="Name">
    		        </div>
    		    </div>
    		    <div class="col-xs-12 col-sm-12 col-md-12">
    		        <div class="form-group">
    		            <strong>Detail:</strong>
    		            <textarea class="form-control" style="height:150px" name="detail" placeholder="Detail"></textarea>
    		        </div>
    		    </div>
    		    <div class="col-xs-12 col-sm-12 col-md-12 text-center">
    		            <button type="submit" class="btn btn-primary">Submit</button>
    		    </div>
    		</div>
        </form>
    
    @endsection

    resources/views/products/edit.blade.php

    @extends('layouts.app')
    
    
    @section('content')
        <div class="row">
            <div class="col-lg-12 margin-tb">
                <div class="pull-left">
                    <h2>Edit Product</h2>
                </div>
                <div class="pull-right">
                    <a class="btn btn-primary" href="{{ route('products.index') }}"> Back</a>
                </div>
            </div>
        </div>
    
    
        @if ($errors->any())
            <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
    
    
        <form action="{{ route('products.update',$product->id) }}" method="POST">
        	@csrf
            @method('PUT')
    
    
             <div class="row">
    		    <div class="col-xs-12 col-sm-12 col-md-12">
    		        <div class="form-group">
    		            <strong>Name:</strong>
    		            <input type="text" name="name" value="{{ $product->name }}" class="form-control" placeholder="Name">
    		        </div>
    		    </div>
    		    <div class="col-xs-12 col-sm-12 col-md-12">
    		        <div class="form-group">
    		            <strong>Detail:</strong>
    		            <textarea class="form-control" style="height:150px" name="detail" placeholder="Detail">{{ $product->detail }}</textarea>
    		        </div>
    		    </div>
    		    <div class="col-xs-12 col-sm-12 col-md-12 text-center">
    		      <button type="submit" class="btn btn-primary">Submit</button>
    		    </div>
    		</div>
    
    
        </form>
    
    
    
    @endsection
    

    resources/views/products/show.blade.php

    @extends('layouts.app')
    
    
    @section('content')
        <div class="row">
            <div class="col-lg-12 margin-tb">
                <div class="pull-left">
                    <h2> Show Product</h2>
                </div>
                <div class="pull-right">
                    <a class="btn btn-primary" href="{{ route('products.index') }}"> Back</a>
                </div>
            </div>
        </div>
    
    
        <div class="row">
            <div class="col-xs-12 col-sm-12 col-md-12">
                <div class="form-group">
                    <strong>Name:</strong>
                    {{ $product->name }}
                </div>
            </div>
            <div class="col-xs-12 col-sm-12 col-md-12">
                <div class="form-group">
                    <strong>Details:</strong>
                    {{ $product->detail }}
                </div>
            </div>
        </div>
    @endsection

    now everything is ready but we need some dummy content to test this if we adding it manually it’s take time and we irrigated from that so let’s setup Seeders

    Seeder Setup

    Now we will create seeder for permissions, Right now we have fixed permission so we create using seeder as described bellow, but if you want add more permission you can do it as you want.

    • role-list
    • role-create
    • role-edit
    • role-delete
    • product-list
    • product-create
    • product-edit
    • product-delete

    Let’s Create Permission Seeder first

    php artisan make:seeder PermissionSeeder

    Now Put below code to your

    database/seeds/PermissionSeeder.php

    <?php
      
    namespace Database\Seeders;
      
    use Illuminate\Database\Seeder;
    use Spatie\Permission\Models\Permission;
      
    class PermissionSeeder extends Seeder
    {
        /**
         * Run the database seeds.
         *
         * @return void
         */
        public function run()
        {
            $permissions = [
               'role-list',
               'role-create',
               'role-edit',
               'role-delete',
               'product-list',
               'product-create',
               'product-edit',
               'product-delete'
            ];
         
            foreach ($permissions as $permission) {
                 Permission::create(['name' => $permission]);
            }
        }
    }

    After this we have to run bellow command for run PermissionSeeder :

    php artisan db:seed --class=PermissionSeeder

    write below code into UserSeeder

    database/seeds/UserSeeder.php

    <?php
      
    namespace Database\Seeders;
      
    use Illuminate\Database\Seeder;
    use App\Models\User;
    use Spatie\Permission\Models\Role;
    use Spatie\Permission\Models\Permission;
      
    class CreateAdminUserSeeder extends Seeder
    {
        /**
         * Run the database seeds.
         *
         * @return void
         */
        public function run()
        {
            $user = User::create([
                'name' => 'Admin User', 
                'email' => 'admin@gmail.com',
                'password' => bcrypt('password')
            ]);
        
            $role = Role::create(['name' => 'Admin']);
         
            $permissions = Permission::pluck('id','id')->all();
       
            $role->syncPermissions($permissions);
         
            $user->assignRole([$role->id]);
        }
    }

    Run above UserSeeder using below command

    php artisan db:seed --class=User

    Congratulations 🎉 We completed our task and now Let’s see the result

    start the server using below commands

    php artisan serve

    Access By

    http://localhost:8000/

    Now you can login with following credential

    Email: admin@gmail.com
    Password: password

    Now you can run and check.

    References

    Categorized in:

    Laravel,

    Last Update: July 27, 2024

    Tagged in:

    , ,