Laravel 8-has , doesnthave , whereHas , scope

Tamrakar Shreyaa
7 min readMay 1, 2021

--

Install Laravel Project

Run the command to induct fresh Laravel project.

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

Setting Up Model and Migrations

php artisan make:model Category -mphp artisan make:model Position -m

Open app\Category.php file, and place the following code.

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Category extends Model
{
use HasFactory;
protected $table="categories";
protected $fillable=['title'];

public function positions()
{
return $this->hasMany(Position::Class);
}

// get category data using scope function
public function scopegetCategory($query)
{
return $query->get();
}

}

Open app\Position.php file, and place the following code.

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Position extends Model
{
use HasFactory;
protected $table='positions';
protected $fillable=['title','category_id','status'];

public function Category()
{
return $this->belongsTo(Category::Class);
}
}

Open database/migrations/timestamp_create_categories_table.php and add the form values that we need to store in the database.

<?php

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

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

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

Open database/migrations/timestamp_create_positions_table.php and add the form values that we need to store in the database.

<?php

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

class CreatePositionsTable extends Migration
{
/**
* Run the migrations.
*
*
@return void
*/
public function up()
{
Schema::create('positions', function (Blueprint $table) {
$table->id();
$table->string('title');
$table->integer('status');
$table->integer('categories_id');
$table->timestamps();
});
}

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

Execute the following command to migrate the database values, verify the table created with the values mentioned above in the MySQL database.

php artisan migrate

Define Controller & Route

Please create a new controller, and It will have the logic to display the project’s list. Run the command to create the controller.

php artisan make:controller CategoryController -rphp artisan make:controller PositionController -r

Open app/Http/Controllers/CategoryController.php and add the following code.

<?php

namespace App\Http\Controllers;

use App\Models\Category;
use Illuminate\Http\Request;

class CategoryController extends Controller
{
/**
* Display a listing of the resource.
*
*
@return \Illuminate\Http\Response
*/
public function index()
{
// get category data which has position
$category = Category::has('positions')->get();
return view('category.index',compact('category'));

// get category data which doesnt have position
$category = Category::doesnthave('positions')->get();
return view('category.index',compact('category'));

// get category data which has status=1 poistion only
$category = Category::whereHas('positions', function($q){
$q->where('status', '1');
})->get();
return view('category.index',compact('category'));

// using scope funtion
$category = Category::getCategory();
return view('category.index',compact('category'));


}

/**
* 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)
{
$category =new Category();
$category->fill($request->all());
$category->save();
return back();
}

/**
* Display the specified resource.
*
*
@param \App\Models\Category $category
*
@return \Illuminate\Http\Response
*/
public function show(Category $category)
{
//
}

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

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

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

Open app/Http/Controllers/PositionController.php and add the following code.

<?php

namespace App\Http\Controllers;

use App\Models\Category;
use App\Models\Position;
use Illuminate\Http\Request;

class PositionController extends Controller
{
/**
* Display a listing of the resource.
*
*
@return \Illuminate\Http\Response
*/
public function index()
{
$category = Category::all();
$position=Position::all();
return view('position.index', compact('category','position'));
}

/**
* 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)
{
$position = new Position();
$position->fill($request->all());
$position->status=1;
$position->save();
return back();
}

/**
* Display the specified resource.
*
*
@param \App\Models\Position $position
*
@return \Illuminate\Http\Response
*/
public function show(Position $position)
{
//
}

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

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

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

Define Route

Open routes/web.php and insert the following code. It will create relation between the controller & the view over and above that it will also invoke the pdf download.

<?php

use Illuminate\Support\Facades\Route;

/*
|--------------------------------------------------------------------------
| 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');
});


Route::get('/category', [App\Http\Controllers\CategoryController::class, 'index'])->name('category');
Route::post('/add-category', [App\Http\Controllers\CategoryController::class, 'store'])->name('add.category');Route::get('/position', [App\Http\Controllers\PositionController::class, 'index'])->name('position');Route::post('/add-position', [App\Http\Controllers\PositionController::class, 'store'])->name('add.position');

Display Category Index in Blade View Template

Generate a blade file resources/views/category/index.blade.php then insert the following code inside.

<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title class="text-center">Laravel 8 </title>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css">


<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
body {
font-family: Arial, Helvetica, sans-serif;
}

/* The Modal (background) */
.modal {
display: none; /* Hidden by default */
position: fixed; /* Stay in place */
z-index: 1; /* Sit on top */
padding-top: 100px; /* Location of the box */
left: 0;
top: 0;
width: 100%; /* Full width */
height: 100%; /* Full height */
overflow: auto; /* Enable scroll if needed */
background-color: rgb(0, 0, 0); /* Fallback color */
background-color: rgba(0, 0, 0, 0.4); /* Black w/ opacity */
}

/* Modal Content */
.modal-content {
background-color: #fefefe;
margin: auto;
padding: 20px;
border: 1px solid #888;
width: 80%;
}

/* The Close Button */
.close {
color: red;
float: left;
font-size: 28px;
font-weight: bold;
}

.close:hover,
.close:focus {
color: #000;
text-decoration: none;
cursor: pointer;
}
</style>
</head>
<body>
<div class="container mt-5">
<div class="col-md">
<button class="btn btn-primary" id="myBtn">Add Category</button>
</div>

<!-- The Modal -->
<div id="myModal" class="modal">

<!-- Modal content -->
<div class="modal-content">
<span class="close">&times;</span>
<span class=" text-primary text-black">Add Category</span> <br>
<form method="POST" action="{{route('add.category')}}" class="w-100 create-form">
@csrf
<div class="row">
{{--title--}}
<div class="col-md-4">
<div class="form-group">
<label for="">Title</label>
<input type="text" class="form-control" name="title" value="{{old('title')}}" required>
<label class="error ">{{$errors->first('title')}}</label>
</div>
</div>

</div>


<div class="row">
<div class="col-md-3">
<button type="submit" class="btn btn-primary d-block w-100" id="btnSubmit">submit<i
class="far fa-arrow-right ml-2"></i>
</button>
</div>
</div>

</form>

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

<div class="container mt-5">

@foreach($category as $c)
<h1 class="text-center">{{$c->title}}</h1>

@endforeach
</div>

<script>
// Get the modal
var modal = document.getElementById("myModal");

// Get the button that opens the modal
var btn = document.getElementById("myBtn");

// Get the <span> element that closes the modal
var span = document.getElementsByClassName("close")[0];

// When the user clicks the button, open the modal
btn.onclick = function () {
modal.style.display = "block";
}

// When the user clicks on <span> (x), close the modal
span.onclick = function () {
modal.style.display = "none";
}

// When the user clicks anywhere outside of the modal, close it
window.onclick = function (event) {
if (event.target == modal) {
modal.style.display = "none";
}
}


</script>
</body>

</html>

Generate a blade file resources/views/position/index.blade.php then insert the following code inside.

<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title class="text-center">Laravel 8 </title>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css">


<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
body {
font-family: Arial, Helvetica, sans-serif;
}

/* The Modal (background) */
.modal {
display: none; /* Hidden by default */
position: fixed; /* Stay in place */
z-index: 1; /* Sit on top */
padding-top: 100px; /* Location of the box */
left: 0;
top: 0;
width: 100%; /* Full width */
height: 100%; /* Full height */
overflow: auto; /* Enable scroll if needed */
background-color: rgb(0, 0, 0); /* Fallback color */
background-color: rgba(0, 0, 0, 0.4); /* Black w/ opacity */
}

/* Modal Content */
.modal-content {
background-color: #fefefe;
margin: auto;
padding: 20px;
border: 1px solid #888;
width: 80%;
}

/* The Close Button */
.close {
color: red;
float: left;
font-size: 28px;
font-weight: bold;
}

.close:hover,
.close:focus {
color: #000;
text-decoration: none;
cursor: pointer;
}
</style>
</head>
<body>
<div class="container mt-5">



<div class="col-md">
<button class="btn btn-primary" id="myBtn">Add Position</button>
</div>

<!-- The Modal -->
<div id="myModal" class="modal">

<!-- Modal content -->
<div class="modal-content">
<span class="close">&times;</span>
<span class=" text-primary text-black">Add Position</span> <br>
<form method="POST" action="{{route('add.position')}}" class="w-100 create-form">
@csrf
<div class="row">
{{--title--}}
<div class="col-md-4">
<div class="form-group">
<label for="">Title</label>
<input type="text" class="form-control" name="title" value="{{old('title')}}" required>
<label class="error ">{{$errors->first('title')}}</label>
</div>
</div>

<div class="col-md-4">
<div class="form-group">
<label for="">Category</label>
<select class="form-control selectpicker"
name="category_id">
<option>select</option>

@foreach($category as $c)
<option
value="{{$c->id}}">

{{ $c->title }}
</option>
@endforeach
</select>
</div>
</div>


</div>


<div class="row">
<div class="col-md-3">
<button type="submit" class="btn btn-primary d-block w-100" id="btnSubmit">submit<i
class="far fa-arrow-right ml-2"></i>
</button>
</div>
</div>

</form>

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

<div class="container mt-5">

@foreach($position as $p)

<h1 class="text-center">{{$p->title}}</h1>
{{-- <p>{{$p->categories_id}}</p>--}}

@endforeach
</div>

<script>
// Get the modal
var modal = document.getElementById("myModal");

// Get the button that opens the modal
var btn = document.getElementById("myBtn");

// Get the <span> element that closes the modal
var span = document.getElementsByClassName("close")[0];

// When the user clicks the button, open the modal
btn.onclick = function () {
modal.style.display = "block";
}

// When the user clicks on <span> (x), close the modal
span.onclick = function () {
modal.style.display = "none";
}

// When the user clicks anywhere outside of the modal, close it
window.onclick = function (event) {
if (event.target == modal) {
modal.style.display = "none";
}
}





</script>
</body>
</html>

--

--

Tamrakar Shreyaa
Tamrakar Shreyaa

Written by Tamrakar Shreyaa

Laravel | PHP | Node| nestjs |API | AJAX | jQuery | Laravel vue | Livewire | LAMP stack | CI CD

No responses yet