Laravel 8-has , doesnthave , whereHas , scope
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">×</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">×</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>