Im new to laravel eloquent and i want to know if that loading times are normally with only five entries
Even a simple select all query has ~720 ms specially on edit button that is first photo (modal) the data comes after one second that is noticeable, Im using Livewire i dont know if affect that too much
{{ $customer->services->count()}}
table as you can see runs on each row that is wrong because adds extra loading time. $sql = "SELECT name,vat,id";
$sql .= " ,(select sum(taskcharges) from charges where charges.customers_id=customers.id) as taskcharges_sum";
$sql .= " ,(select sum(payment) from charges where charges.customers_id=customers.id) as payment_sum";
$sql .= " ,(select sum(taskcharges-payment) from charges where charges.customers_id=customers.id) as balance_sum";
$sql .= " ,(select name WHERE customers.id=$id) ";
$sql .= " FROM customers ";
I want to have access from Customers on specific child(services) columns to make functions like max,sum,count the tables are binded on model so i want to avoid extra code of join queries plus as you can see on sorting the "services" isnt column of Customers table so they dont recognize the column services on customers table, if i had something like "select count(services) as servicecount then i will able to recognize the sorting as new column of the table customers
Above you can see my code:
customers/show.blade.php:
<div class="container">
<p>Sort column:{{$selectedItems}}</p>
<p>Selected Direction:{{$action}}</p>
<!-- Button trigger modal -->
<button wire:click.prevent="addNew" type="button" class="btn btn-primary">
Add New User
</button>
<!-- button triger Modal -->
<div class="modal fade" id="form" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">Insert</h5>
<button type="button" wire:click.prevent="close"class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
@livewire('customers.form')
</div>
</div>
</div>
</div>
<div class="modal fade" id="delete" tabindex="-1" role="dialog" aria-labelledby="delete" aria-hidden="true" wire:ignore>
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="delete">Delete</h5>
<button type="button" wire:click.prevent="close" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<h3>Do you wish to continue?</h3>
</div>
<div class="modal-footer">
<button type="button" wire:click="close" class="btn btn-secondary" data-dismiss="modal">Cancel</button>
<button wire:click="delete" class="btn btn-primary">Delete</button>
</div>
</div>
</div>
</div>
<h1 class="text-center">Customers {{count($customers)}}</h1>
<div>
<div class="w-full flex pb-10">
<div class="w-3/3 mx-1">
<input wire:model.debounce.300ms="search" type="text" class="form-control" placeholder="Search users...">
</div>
<div class="row mb-4">
<div class="col form-inline">
Per Page:
<select wire:model="perPage" class="form-control">
<option>5</option>
<option>10</option>
</select>
</div>
</div>
</div>
<table class="table-auto w-full mb-6">
<thead>
<tr>
<th wire:click="sortBy('id')" style="cursor: pointer;" class="px-4 py-2">ID
@include('layouts.partials.sort_icons',['field'=>'id'])
</th>
<th wire:click="sortBy('name')" style="cursor: pointer;" class="px-4 py-2">Name
@include('layouts.partials.sort_icons',['field'=>'id'])</th>
<th wire:click="sortBy('plate')" style="cursor: pointer;" class="px-4 py-2">Plate
@include('layouts.partials.sort_icons',['field'=>'id'])</th>
<th wire:click="sortBy('services')" style="cursor: pointer;" class="px-4 py-2">Services
@include('layouts.partials.sort_icons',['field'=>'services'])</th>
<th class="px-2 py-2">Action</th>
</tr>
</thead>
<tbody>
@foreach($customers as $customer)
<tr>
<td class="border px-4 py-2">{{ $customer->id }}</td>
<td class="border px-4 py-2">{{ $customer->name }}</td>
<td class="border px-4 py-2">{{ $customer->plate }}</td>
<td class="border px-4 py-2">{{ $customer->services->count()}}</td>
<td class="border px-2 py-2">
<button wire:click="selectItem({{$customer->id}},'update')" class="btn btn-info"><i class="fa fa-edit"></I></button></a>
<button wire:click="selectItem({{$customer->id}},'delete')" class="btn btn-danger"><i class="fa fa-trash"></I></button></a>
</td>
</tr>
@endforeach
</tbody>
</table>
<div class="paginate">{{$customers->links()}}</div>
</div>
</div>
customers/Show.php :
<?php
namespace App\Http\Livewire\Customers;
use App\Models\Customer;
use Livewire\Component;
use App\Page;
use Illuminate\Support\Str;
use App\Http\Livewire\Column;
use Livewire\WithPagination;
class Show extends Component
{
public $sortBy= 'name';
public $sortDirection = 'asc';
public $headers;
public $perPage ='5';
public $search;
public $action;
public $selectedItems;
public function sortBy($field){
if ($this->sortDirection =='asc'){
$this ->sortDirection ='desc';
}
else{
$this->sortDirection ='asc';
}
return $this ->sortBy = $field;
}
public function selectItem($itemId,$action){
$this->selectedItems=$itemId;
$this->action=$action;
if ($action=='delete'){
$this->dispatchBrowserEvent('show-deletemodal');
} else{
$this->emit('getcustomerID', $this->selectedItems);
$this->dispatchBrowserEvent('show-modal');
}
}
public function delete(){
Customer::destroy($this->selectedItems);
$this->dispatchBrowserEvent('hide-modal');
}
public function addNew()
{
$this->dispatchBrowserEvent('show-modal');
}
public function close()
{
$this->dispatchBrowserEvent('hide-modal');
}
protected $listeners = [
'deleteconfirmed'=>'$selectedItems',
'refreshParent'=>'$refresh'
];
public function render()
{
$customers = Customer::query()
->search($this->search)
->orderBy($this->sortBy,$this->sortDirection)
->paginate($this->perPage);
return view('livewire.customers.show',['customers'=>$customers
])
->extends('admin.dashboard')
->section('content');
}
}
customers/form.php :
<?php
namespace App\Http\Livewire\Customers;
use App\Models\Customer;
use Livewire\Component;
class Form extends Component
{
public $name ='';
public $plate = '';
public $customerId ;
protected $listeners = [
'getcustomerID'
];
protected function rules() {
return [
'name' => 'required',
'plate' => ['required', 'regex:/[A-Z]{3}\d{4}$/','unique:customers,plate,' . $this->customerId],
];
}
public function updated($propertyName)
{
$this->validateOnly($propertyName);
}
public function getcustomerID($customerId){
$this->customerId=$customerId;
$customer= customer::find ($this->customerId);
$this->name=$customer->name;
$this->plate= $customer->plate;
}
public function save()
{
$this->validate();
$data = [
'name' => $this->name,
'plate' => $this->plate,
];
if ($this->customerId){
customer::find ($this->customerId)->update($data);
session()->flash('message', 'User successfully updated.');
} else{
customer::create($data);
}
$this->emit('refreshParent');
$this->dispatchBrowserEvent('hide-modal');
$this ->ClearVars();
}
public function ClearVars(){
$this->name=null;
$this->plate=null;
}
public function render()
{
return view('livewire.customers.form');
}
}
Models/Customer.php
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Customer extends Model
{
use HasFactory;
protected $fillable = [
'name',
'plate'
];
public function services()
{
return $this->hasMany(Service::class);
}
public function parts()
{
return $this->hasMany(Part::class, 'customer_id');
}
public function scopeSearch($query , $val){
return $query
->where('name','like','%'.$val.'%')
->Orwhere('plate','like','%'.$val.'%');
}
public function user()
{
return $this->belongsTo(User::class);
}
}
Models/Services.php
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Service extends Model
{
protected $fillable = [
'service_type',
'km',
];
public function customer()
{
return $this->belongsTo(Customer::class);
}
public function parts()
{
return $this->hasMany(part::class);
}
}
It was so simple.. just added ->withCount('services')
above of query
Still have that strange delay
Update : The problem with slow response was that trying to retrieve data from remote sql server, I change to local and I have less than 100ms!