Laravel eloquent delete - laravel

I am looking for some assistance on how to understand Laravel Eloquent model.
I need to delete User by Id, and I have tables Main_info, Personal_info, Holidays, other_info, fm_day, oth_daysoff.
On the tables, I have inserted UserId field, so I need to delete selected UserId from all of the tables? May someone help me on how I can do this with Laravel Eloquent model?
Here is my view with delete submit button and post method:
<div class="container">
<div class="row">
<div class="col">
<div class="card">
<div class="card-head-man">
<span>Filter type: </span>
Position
Active/No
Employment type
Location
</div>
</div>
</div>
<div class="col-12">
<div class="card">
<div class="card-header">
<h3 class="card-title">List of employees</h3>
</div>
<div class="table-responsive">
<table class="table card-table table-vcenter text-nowrap">
<thead>
<tr>
<th class="w-1">ID<span class="caret"></span></th>
<th>First Name<span class="caret"></span></th>
<th>Last Name</th>
<th>Position</th>
<th>Active/no</th>
<th>Employment type</th>
<th>Location</th>
<th></th>
<th></th>
</tr>
</thead>
<tbody>
#foreach($allData as $data)
<tr>
<td><span class="text-muted">{{ $data->id }}</span></td>
<td>{{ $data->first_name }}</td>
<td>
{{ $data->last_name }}
</td>
<td>
{{ $data->position }}
</td>
<td>
{{ $data->employment_type }}
</td>
<td>
<span class="status-icon bg-success"></span> Active
<span class="status-icon bg-danger"></span> No
</td>
<td>{{ $data->location }}</td>
<td class="text-right">
Manage
<div class="dropdown">
<form action="/deleteFromHome" method="post">
{{csrf_field()}}
<input style="display: none;" type="text" name="deleteUserId" class="form-control" id="inputName3" value="{{ $data->id }}">
<button type="submit" class="btn btn-secondary btn-sm">Delete</button>
</form>
</div>
</td>
<td>
<a class="icon" href="javascript:void(0)">
<i class="fe fe-edit"></i>
</a>
</td>
</tr>
#endforeach
</tbody>
</table>
</div>
</div>
</div>
Here is how my controller doing it now:
public function deleteUserFromHome(Request $req)
{
$userId = $req->input('deleteUserId');
OtherInfo::where('id', $userId)->delete();
OthDaysInfo::where('id', $userId)->delete();
HolidaysInfo::where('id', $userId)->delete();
FMdaysInfo::where('id', $userId)->delete();
PersonalInfo::where('id', $userId)->delete();
PersonalInfo::where('id', $userId)->delete();
MainInfo::where('id', $userId)->delete();
return redirect('home');
}
Maybe there is some better way to delete all data from all tables about selected userId?
I need some example how I can make Laravel Eloquent model to delete with function HasMany or some else?

You can use ->onDelete('cascade')when you create your table migrations.
For instance,
// consider a sample migration below for a table with a foreign key on your users table
Schema::create('main_info', function (Blueprint $table) {
$table->increments('id');
$table->integer('user_id');
$table->foreign('user_id')
->references('id')
->on('users')
->onDelete('cascade');
$table->timestamps();
});
And then you can easily just delete the specified user, and Laravel will take care of deleting it's child records.
$user = User::find($id);
$user->delete(); // this will also delete any record for this user on main_info table
Read more here

Related

how to update an array in laravel

i have an array of data in a form that i want to update.when i update only the last column updated while the inputs that i updated do change.for example, we have a column size, price, and stock. the size include small,medium, and large and their respective prices and stock number. when i update the price of small size,it doesnt update but rather it updates the medium size.same for the large size also.i havent understood why only a specfic column is updating yet i have added a foreach to loop all the columns when updating.here is my update function.
public function editattributes(Request $request,$id)
{
$merchadisedata=Merchadise::select('id','merch_name','merch_code','merch_image')->find($id);
if ($request->isMethod('post')){
$data=$request->all();
foreach($data['attrid'] as $key=>$attr){
if(!empty($attr)){
Productattribute::where(['id'=>$data['attrid'][$key]])
->update([
'productattr_price'=>$data['productattr_price'][$key],
'productattr_stock'=>$data['productattr_stock'][$key],
]);
}
$message='Product attributes have been updated successfully';
Session::flash('success_message',$message);
return redirect()->back();
}
}
return view('backend.merchadise.editproductattributes')->with(compact('merchadisedata'));
}
on dd($data);die(); i get the inputs i have filled
here is the form in the blade file that am submitting
<form method="post" action="{{ url('admin/edit-attributes/'.$merchadisedata->id) }}">
{{csrf_field()}}
<table id="products" class="table table-striped table-bordered nowrap" style="width:100%;">
<thead>
<tr>
<th>Attribute Size</th>
<th>Attribute Stock</th>
<th>Attribute Price</th>
<th>Attribute Sku</th>
</tr>
</thead>
<tbody>
#foreach ( $merchadisedata->merchadiseattributes as $attribute)
<input type="text" name="attrid[]" value="{{ $attribute->id }}" style="display: none"/>
<tr>
<td>{{ $attribute->productattr_size}}</td>
<td>
<input type="number" name="productattr_stock[]" value="{{ $attribute->productattr_stock }}" required=""/>
</td>
<td>
<input type="number" name="productattr_price[]" value="{{ $attribute->productattr_price }}" required=""/>
</td>
<td>{{ $attribute->productattr_sku }}</td>
</tr>
#endforeach
</tbody>
</table>
<div class="form-group">
<button type="submit" class="btn btn-primary btn-sm btn-block">Submit</button>
</div>
</form>
where might i be going wrong in my code

How to create a template view table tag without repeating table tags on every file

I'm developing a system which has many tables so I have to repeat the writing of table tags on all the files which display a table
Here is what I'm doing on every file which have to display table
On Countries table:
<table class="table table-striped table-hover table-sm" id="table">
<thead class="text-uppercase text-center bg-primary">
<tr class="text-white">
<th scope="col">Name</th>
<th scope="col">Slug</th>
<th scope="col">Population</th>
<th scope="col">Region</th>
<th scope="col">Cities</th>
<th scope="col">Descriptions</th>
<th scope="col" >Actions</th>
</tr>
{{ csrf_field() }}
</thead>
<tbody>
#foreach ($countries as $country)
<tr>
<td class="text-left">{{$country->name}}</td>
<td class="text-center">{{$country->slug}}</td>
<td class="text-right">{{$country->population}}</td>
<td class="text-center">{{$country->region->name}}</td>
<td class="text-center">{{$country->city_count}}</td>
<td class="text-left">{{$country->desc}}</td>
<td class="text-center">
<div class="btn-group">
#can('country-update')
<a class="btn btn-primary btn-sm mr-2" href="{{route('location.countries.edit',$country)}}" title="Edit"><i class="fa fa-edit"></i></a>
#endcan
#can('country-delete')
<form class="form-delete" method="post" action="{{route('location.countries.destroy',$country)}}">
#method('DELETE')
#csrf
<button type="submit" class="btn btn-danger btn-sm" onclick="return confirm('Are you sure?')"><i class="fa fa-trash-alt"></i></button>
</form>
#endcan
</div>
</td>
</tr>
#endforeach
</tbody>
</table>
then on the cities I'll do the same but with different table head names and table data
<table class="table table-striped table-hover table-sm" id="table">
<thead class="text-uppercase text-center bg-primary">
<tr class="text-white">
<th scope="col">Name</th>
<th scope="col">Slug</th>
<th scope="col">Country</th>
<th scope="col">Descriptions</th>
<th scope="col" >Actions</th>
</tr>
{{ csrf_field() }}
</thead>
<tbody>
#foreach ($cities as $city)
<tr>
<td class="text-left">{{$city->name}}</td>
<td>{{$city->slug}}</td>
<td class="text-center">{{$city->country->name}}</td>
<td class="text-left">{{$city->desc}}</td>
<td class="text-center">
<div class="btn-group">
#can('city-update')
<a class="btn btn-primary btn-sm mr-3" href="{{route('location.cities.edit',$city)}}" title="Edit"><i class="fa fa-edit"></i></a>
#endcan
#can('city-delete')
<form class="form-delete" method="post" action="{{route('location.cities.destroy',$city)}}">
#method('DELETE')
#csrf
<button type="submit" class="btn btn-danger btn-sm" onclick="return confirm('Are you sure?')" title="delete"><i class="fa fa-trash-alt"></i></button>
</form>
#endcan
</div>
</td>
</tr>
#endforeach
</tbody>
</table>
but I wat to have a template where I'll only populate table head rows and table body something like this
<div class="table-responsive">
<table class="table table-striped table-hover table-sm" id="table">
<thead class="text-uppercase text-center">
<tr>
//Dynamic table heads
#if(!is_null($rows))
#foreach($rows as $row)
{{$row}}
#endforeach
#endif
</tr>
</thead>
<body>
//Dynamic table body
#if(!is_null($datas))
#foreach($datas as $data)
{{$data}}
#endforeach
#endif
</tbody>
</table>
<!-- end table -->
</div>
What is the best way to accomplish this
You can use Blade component for that. One of approaches in Laravel 7 is to use Blade class component. Link to official Blade components docs: https://laravel.com/docs/7.x/blade#components
You can create a generic table component using artisan command:
php artisan make:component Table
Component class
Your component could look like that:
<?php
namespace App\View\Components;
use Illuminate\View\Component;
class Table extends Component
{
/**
* Array of table heading strings
*
* #var array
*/
public $headings;
/**
* Table rows
*
* #var array
*/
public $rows;
/**
* Create the component instance.
*
* #param string $type
* #param string $message
* #return void
*/
public function __construct($headings, $rows)
{
$this->headings = $headings;
$this->rows = $rows;
}
/**
* Get the view / contents that represent the component.
*
* #return \Illuminate\View\View|string
*/
public function render()
{
return view('components.table');
}
}
Component view
Now when you have component class, you have to prepare the component view. You will found it in /resources/views/components/table.blade.php.
<div class="table-responsive">
<table class="table table-striped table-hover table-sm" id="table">
//Dynamic table heads
#if($headings)
<thead class="text-uppercase text-center">
<tr>
#if($rows))
#foreach($rows as $row)
<th>{{$row}}</th>
#endforeach
#endif
</tr>
</thead>
#endif
<tbody>
//Dynamic table body
#foreach($rows as $row)
<tr>
// Render each item from row
#foreach($row as $item)
<td>{{$item}}</td>
#endforeach
</tr>
#endif
</tbody>
</table>
<!-- end table -->
</div>
Now you can use your component in your views:
<x-table :headings="['foo', 'bar']"
:data="[['foo1', 'bar1'], ['foo2', 'bar2']]" class="mt-4"/>

Why is The Entire Body of the Web page loaded to the table instead of the data when retrieving data from the database using ajax in Larvel

I have this table showing all the encashment records, it works fine but when I try to get the rows from the database within a specific range of dates and display it to the same table, the whole body of the webpage is being loaded to the table instead of the rows from the database.
Please see image below:
this is my function from the tableController.php
function encashmentRecord_DateRange(Request $request){
if($request->ajax())
{
$start = $request->get('startDate');
$end = $request->get('endDate');
$data = DB::table('encashment_requests')->whereBetween('date',[$start,$end])->get();
return view('incashment',compact('data'));
}
}
the script in my encashment.blade.php
$(document).ready(function(){
$('#dataTable').DataTable();
$('#start_date').datepicker({
format:'yyyy-mm-dd',
autoclose:true
}).val();
$('#end_date').datepicker({
format:'yyyy-mm-dd',
autoclose:true
}).val();
var range = document.getElementById('btnrange');
range.addEventListener('click',function(){
var start_date = $('#start_date').val();
var end_date =$('#end_date').val();
alert(end_date);
$('#dataTable').DataTable().destroy();
listDateRange(start_date,end_date);
},false);
function listDateRange(startDate,endDate){
$.ajax({
method: 'GET',
url : "{{ route('encashmentRecord.action') }}",
data: {startDate:startDate, endDate:endDate},
success:function(data)
{
alert(data);
$('#dataTable').html(data);
}
})
}
});
If you only need the data, you shouldn't be returning view() from your controller.
Try replacing it with this: return response()->json($data, 200);
I may have found the solution to my problem, though it may look lengthy. But it worked.
I made another view, encashmentRecord.blade, containing only the table, so in the controller, instead of returning the data in the incashment.blade, I returned the data to the new view, encashentRecord.blade and I use "#include('encashmentRecord')" in my incashment.blade to display the table.
encashmentRecord.blade.php
<div class="card-body">
<table id="dataTable" class="table table-striped table-bordered">
<thead>
<tr>
<th>Name</th>
<th>Account ID</th>
<th class="sort">Date</th>
<th>Desired Ammount</th>
<th>Destination</th>
<th>Status</th>
</tr>
</thead>
<tbody>
#if(isset($data))
#foreach($data as $row)
<tr>
<td>{{ $row->account_name}}</td>
<td>{{ $row->account_id}}</td>
<td>{{ $row->created_at}}</td>
<td>Php {{ $row->requested_ammount}}</td>
<td>{{ $row->destination}}</td>
<td>{{ $row->status}}</td>
</tr>
#endforeach
#else
<tr>
No Data
</tr>
#endif
</tbody>
</table>
and this is incashment.blade.php
<div class="row">
<div class="col-xl-3 ">
<input type="text" name="query" id="start_date" class="form-control input_daterange">
</div>
<div class="col-xl-3 ">
<input type="text" name="query" id="end_date" class="form-control">
</div>
<div class="col-xl-3 ">
<button class="btn" id="btnrange">Go</button>
</div>
</div>
<div class="card" style="margin-bottom: 0px">
<div class="card-header">
Encashment Record
</div>
<div id="table_data">
#include('tables.encashmentRecord')
</div>
</div>
I just change the view in my return on the controller
return view('tables.encashmentRecord',compact('data'));

Display date to view with a M-D-Year

I am new to laravel, with regards to displaying the date to the view with the MM-DD-YYYY format
#extends('layouts.common')
#section('title' ,'Administrator | Category')
#section('contents')
<div class="row">
<div class="col-md-8 col-md-offset-2">
<div class="panel panel-default">
<div class="panel-heading">All Categories</div>
<div class="panel-body">
<table class="table">
<thead class="thead-inverse">
<tr>
<th>Category Name</th>
<th>Published At</th>
</tr>
</thead>
<tbody>
#foreach($categories as $category)
<tr>
<td><a href="{{ url('/category', $category->id) }}"> {{
$category->name }}</a></td>
<td>{{$category->published_at }}</td>
<td><a href="{{ route('category.edit',$category->id) }}"><i
class="icon fa fa-edit"></i>&nbsp&nbsp&nbsp</a><i
class="icon fa fa-times"></i></td>
</tr>
</tbody>
#endforeach
</table>
</div>
</div>
</div>
</div>
#endsection #section('js') {!!Html::script('assets/js/jquery.min.js')!!}
{!!Html::script('assets/js/bootstrap.min.js') !!} #endsection
With regards to that i would like to display to the view the {{$category->published_at }} data into that format. Please help thanks
Please follow way below
{!! date('d-m-Y', strtotime($model->start_date)) !!}
or
{{ date('d-m-Y', strtotime($model->start_date)) }}
I Hope Help You!
In your Category model
public $dates = ['published_at'];
Then in view you can use
$category->published_at->format('m-d-Y')
Further reading: Eloquent: Mutators
Another approach. Extends Skysplit answer
In Category Model
public function getPublishedAtAttribute(){
return $this->attributes['published_at']->format('m-d-Y');
}
And never worry about published_at again. Just
$category->published_at

pagination in laravel 5.3 when count of pages = 1

I have cities table and it has 7 cities I have a view page to display these cities with 10 cities per page
Controller:
$cities = City::orderBy('id', 'desc')->paginate(10);
return view('cities.home', compact('cities'));
View:
<div class="table-responsive panel panel-sky">
<table class="table table-striped table-hover">
<tr>
<th>#</th>
<th>Name</th>
<th>Created At</th>
<th>Action</th>
</tr>
#foreach($cities as $city)
<tr id="product{{$city->id}}">
<td>{{$city->id}}</td>
<td>{{$city->name}}</td>
<td>{{ $city->created_at }}</td>
<td>
<i class="glyphicon glyphicon-edit action-icon"></i>
<a type="button" class="pointer" data-toggle="modal" data-target="#deleteModal" data-type="btn-danger" data-action="delete-product" data-id="{{ $city->id }}" data-msg="Are you sure you want to delete this city?" data-title="Confirm Deletion">
<span class='glyphicon glyphicon-remove action-icon'></span>
</a>
</td>
</tr>
#endforeach
</table>
<div>
<div class="col-md-12"><?php echo $cities->render(); ?> </div>
but the issue is the paginate render is displayed with page#1, this issue occurred in laravel5.3 and did not find in laravel5.2
If you want to render pagination in your own way, you can use paginator methods. For example, to check if there is just one page, you could try:
#if ($cities->total() > 10)
// Render pagination
#endif

Resources