How can I reduce executed queries in Laravel? - laravel

I have about 6 custom attributes on my model, and in my blade view, I loop through filtered models and use these attributes in some if-else statements, but it takes a lot of time to render, as it executes a lot of queries.
Here is an example of an attribute I have.
/**
* Determine if an invoice is due.
*
* #return bool
*/
public function getInvoiceDueAttribute()
{
if (!$this->invoice_frequency) {
return $this->finished && (!$this->invoiced || $this->outgoing_invoices()->whereNull('invoice_number')->count() > 0);
}
$last_invoice = $this->outgoing_invoices()
->where('invoiceable', true)
->latest()
->first();
return ($last_invoice ? $last_invoice->created_at : $this->created_at)
->startOfMonth()->addMonth($this->invoice_frequency)->isPast();
}
Blade:
#foreach($building->projects as $project)
...
<td class="text-center text-nowrap align-middle">
<a href="{{ route('outgoing-invoices.indexPre', ['project' => $project->id]) }}"
class="btn btn-sm btn-{{ $project->invoice_state_color }} #cannot ('Invoice view') disabled #endcannot">
#if ($project->invoice_ok)
<i class="fa fa-check"></i> Számlázva
#elseif ($project->invoice_in_progress)
<i class="fa fa-rotate-right"></i> Folyamatban
#elseif ($project->invoice_due)
<i class="fa fa-times"></i> Számlázatlan
#else
<i class="fa fa-times"></i> Nem esedékes
#endif
</a>
</td>
<td class="text-center text-nowrap align-middle">
#if ($project->invoice_with_project_id)
Havi riportban
#else
<a href="{{ route('outgoing-invoices.index', ['project' => $project->id]) }}"
class="btn btn-sm btn-{{ $project->payment_state_color }} #cannot ('Invoice view') disabled #endcannot">
#if ($project->payment_ok)
<i class="fa fa-check"></i> Nincs fizetetlen számla
#elseif (is_null($project->payment_ok))
<i class="fa fa-times"></i> Nem esedékes
#else
<i class="fa fa-rotate-right"></i> Folyamatban
#endif
</a>
#endif
</td>
...
#endforeach
To be clear, my goal is to improve performance by reducing queries or any other way.
I also accept best-practice advice for any part of my code. Thank you for your help!

Related

Laravel - How to Display Submit Edit and Delete based on is_approved

I have this code in my Laravel-5.8
public function index()
{
$userCompany = Auth::user()->company_id;
$userEmployee = Auth::user()->employee_id;
$identities = DB::table('appraisal_identity')->select('id')->where('company_id', $userCompany)->where('is_current', 1)->first();
$goals = AppraisalGoal::where('employee_id', $userEmployee)->where('appraisal_identity_id', $identities->id)->get();
return view('appraisal.appraisal_goals.index')->with('goals', $goals);
}
view
<td>
#if ($goal->is_approved == 3)
<span class="badge bg-success" >Approved</span>
#elseif ($goal->is_approved == 2)
<span class="badge bg-danger">Not Approved</span>
#elseif ($goal->is_approved == 1)
<span class="badge bg-info">Awaiting Approval</span>
#else
<span class="badge bg-black">Draft</span>
#endif
</td>
<td>
#can('appraisal_goal_show')
<a class="btn btn-xs btn-primary" href="{{ route('appraisal.appraisal_goals.show', $goal->id) }}">
{{ trans('global.view') }}
</a>
#endcan
#can('appraisal_goal_edit')
<a class="btn btn-xs btn-info" href="{{ route('appraisal.appraisal_goals.edit', ['id'=>$goal->id]) }}">
{{ trans('global.edit') }}
</a>
#endcan
#can('appraisal_goal_delete')
<button class="btn btn-xs btn-danger" type="submit" onclick="deleteTag({{ $goal->id }})">
Delete
</button>
<form id="delete-form-{{ $goal->id }}" action="{{ route('appraisal.appraisal_goals.destroy',$goal->id) }}" method="POST" style="display: none;">
#csrf
#method('DELETE')
</form>
#endcan
</td>
<div class="col-12">
<i class="fas fa-arrow-right"></i> Submit
</div>
I want to apply this conditions.
Edit should only be visible when is_approved = 1 or 2 or 3
Delete should only be visible when is_approved = 0 or 2
Submit button should only be visible when is_approved = 1 or 2
How do I achieve these?
Thanks
You may nest each of your buttons inside an #if and check is_approved value with in_array function:
#if(in_array($goal->is_approved, [1, 2, 3]))
#can('appraisal_goal_edit')
<a class="btn btn-xs btn-info" href="{{ route('appraisal.appraisal_goals.edit', ['id'=>$goal->id]) }}">
{{ trans('global.edit') }}
</a>
#endcan
#endif
You may do the same for delete and submit buttons and just change the 2nd argument of in_array.

getting errors when showing data on page using ajax

I am adding a search functionality to my user admin page and I am using AJAX for search but I have not been able to show data on my page. It gives an error.
I have tried adding single quotation or double quotation on every side but it just give me an error every time
this is the controller function:
public function search(Request $request)
{
if($request->ajax())
{
$output = '';
$query = $request->get('query');
if($query != '')
{
$data =User::where('name', 'like', '%'.$query.'%')->get();
}
else
{
$data =User::orderBy('created_at' ,'desc')->get();
}
$total_row = $data->count();
if($total_row > 0)
{
foreach($data as $merchant)//That how i am showing data on the page
{
$output .=
"<tr>
<td>"{$users->name}"
"#if($users->allowded == 0)" //I need to add these if else functionality to my code but these thing are giving error
"#endif"
</td>
<td>{{$users->email}}</td>
<td>{{$users->permission->permission}}</td>
<td>
<a href="#" class="btn btn-xs btn-success">
<span style="padding-right: 16px;">Make Him Salaried User
</span>
</a>
<a href="#" class="btn btn-xs btn-success">
<span style="padding-right: 16px;">Make Him Commesioned User
</span>
</a>
<a href="#" class="btn btn-xs btn-success">
<span style="padding-right: 16px;">Make Him Salaried and Commesionded User
</span>
</a>
</td>
<td>
#if($users->user_status)
<a href="" class="btn btn-xs btn-danger">
<span style="padding-right: 10px;">Make Him Unpaid User
</span>
</a>
#else
<a href="" class="btn btn-xs btn-success">
<span style="padding-right: 16px;">Make Him Paid User
</span>
</a>
#endif
</td>
<td>
#foreach($cashtransfer as $cash)
#if($cash->user_id == $users->id)
{{ $cash->amount}}
#endif
#endforeach
</td>
<td>
#if($users->allowded)
<a href="" class="btn btn-xs btn-danger">
<span style="padding-right: 16px;">Bloack User</span>
</a>
#else
<a href="" class="btn btn-xs btn-success">
<span style="padding-right: 16px;">Allow User</span>
</a>
#endif
</td>
<td>
</td>
<td>
<a href="" class="btn btn-xs btn-danger">
<span style="padding-right: 16px;">Delete User</span>
</a>
</td>
</tr>";
}
}
else
{
//This is The Out Variable which is taking data to the page
$output = '
<tr>
<td align="center" colspan="5">No Data Found</td>
</tr>';
}
$data = array(
'table_data' => $output,
'total_data' => $total_row
);
echo json_encode($data);
}
}
These Are the errors I am getting every time:
// ->when($request->has('query'), function($q){
// $q->where('name','like','%'. request('query').'%');
// })->get();
$data =User::where('name', 'like', '%'.$query.'%')->get();
}
else
{
$data =User::orderBy('created_at' ,'desc')->get();
// $pagi = "<div> {$data->links()}</div>";
}
$total_row = $data->count();
if($total_row > 0)
{
foreach($data as $merchant)
{
$output .= "
<tr>
<td>"{$users->name}"
"#if($users->allowded == 0)"
"#endif"
</td>
<td>{{$users->email}}</td>
<td>{{$users->permission->permission}}</td>
<td> <span style="padding-right: 16px;">Make Him Salaried User</span> <span style="padding-right: 16px;">Make Him Commesioned User</span> <span style="padding-right: 16px;">Make Him Salaried and Commesionded User</span></td>
<td>
#if($users->user_status)
<span style="padding-right: 10px;">Make Him Unpaid User</span>
#else
Why can't I just publish it?
I keep getting errors like I need more details
You cannot use blade inside normal strings. You have to use normal PHP to compose the output:
foreach($data as $merchant)
{
$optionalOutput = $users->allowded == 0 ? 'output if true' : 'output if false';
$output .= "<tr>
<td>{$users->name}
{$optionalOutput}
</td>";
// ...
}
Or you could move the code to a blade view:
foreach($data as $merchant)
{
$output .= view('path.to.view', [$merchant, $users])->render();
}

fail to show allert " No data" when data is does not in database

i am using laravel 5.4 ,, i use filter by serial number, i want to when the serial number is not save in database, show the allert "no data" , but when i filter data serial number is not save to database, the page is not show the allert,,
this is my blade..
#extends('layouts.master')
#section('content')
......................................
<div class="panel panel-default">
#if (!$instrumentType->instruments->isEmpty())
<table class="table">
#foreach ($instruments as $instrument)
<tr>
<td>
Serial Number : {{ $instrument->serial_number }}
#if($instrument->customer !== NULL)
<div class="text-muted"><i class="fa fa-hospital-o" aria-hidden="true"></i> {{ $instrument->customer->name }}</div>
#endif
#if($instrument->contractType !== NULL)
<div class="text-muted"><i class="fa fa-compress" aria-hidden="true"></i> {{ $instrument->contractType->name }}</div>
#endif
</td>
<td>
<div class="pull-right">
<a type="button" href="{{ route('instrument.edit', ['instrumentType' => $instrumentType->id, 'instrument' => $instrument->id]) }}"
class="btn btn-success ">
<i class="fa fa-pencil"></i> Edit
</a>
#if($instrument->customer == NULL || $instrument->contractType == NULL)
<a href="{{ route('instrument.destroy', ['instrumentType' => $instrumentType->id, 'instrument' => $instrument->id]) }}"
data-method="delete" data-confirm="" class="btn btn-danger">
<i class="fa fa-trash"></i> <span class="hidden-xs">Delete</span>
</a>
#endif
</div>
</td>
</tr>
#endforeach
</table>
<div class="paginator text-center">{{ $instruments->links() }}</div>
#else
<div class="panel-body">
<div class="alert alert-warning text-center">No data.</div>
</div>
#endif
</div>
#endsection
.
you can get count of array with :
count($instrumentType->instruments)
add this code as your statement :
#if(count($instrumentType->instruments))
//
#else
//
#endif

How Jump to with collections of data in laravel

I'm implementing the Jump to... functionality in my project. What I want is:
If the user is in the first item the left button is NOT included.
If the user is in the last item the right button is NOT included.
The left button should have a link same with the link before the current/selected item.
The right button should have a link same with the link after the current/selected item.
Please see my code below:
Controller
$course = Course::with([
'assignments' => $undeleted,
'quizzes' => $undeleted,
'add_links' => $undeleted
])->findOrFail($id);
$course_items = collect($course->assignments);
$course_items = $course_items->merge(collect($course->quizzes));
$course_items = $course_items->merge(collect($course->add_links));
$course_items = $course_items->sortBy('item_number');
View
<div class="jump-to">
<div class="pull-right">
<div class="btn-group" role="group">
#foreach($course->topics as $topic)
#foreach(collect($topic->assignments)->merge(collect($topic->quizzes))->merge(collect($topic->add_links))->sortBy('item_number') as $first_item)
#if($first_item->id != $assignment->id)
<a href="#" class="btn btn-primary">
<i class="fa fa-angle-left"></i>
</a>
#endif
<?php break 2; ?>
#endforeach
#endforeach
<div class="btn-group" role="group">
<button type="button" class="btn btn-primary dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
Jump to <div class="caret"></div>
</button>
<ul class="dropdown-menu" role="menu">
#foreach($course->topics as $topic)
<li class="jdivider">
Topic {{ $topic->topic_number }}
</li>
#foreach(collect($topic->assignments)->merge(collect($topic->quizzes))->merge(collect($topic->add_links))->sortBy('item_number') as $topic_item)
<li>
#if($topic_item->item_type() == 'assignment')
<a title="Assignment: {{ $topic_item->name }}" class="regular-link" href="{{ route('assignment.view', ['course_id' => $course->id, 'id' => $topic_item->id]) }}">
<i class="fa fa-tasks"></i> {{ str_limit($topic_item->name, 15) }}
</a>
#elseif($topic_item->item_type() == 'quiz')
<a title="Quiz: {{ $topic_item->name }}" class="regular-link" href="{{ route('quiz.view', ['course_id' => $course->id, 'id' => $topic_item->id]) }}">
<i class="fa fa-file-text"></i> {{ str_limit($topic_item->name, 15) }}
</a>
#elseif($topic_item->item_type() == 'add_link')
<a href="#">
#if(!empty($topic_item->file_location) && in_array(strtolower(last(explode('.', $topic_item->file_location))), ['pdf', 'docx', 'doc']))
<i class="fa fa-file-pdf-o"></i>
#elseif(empty($topic_item->file_location))
<i class="fa fa-globe"></i>
#else
<i class="fa fa-file-text-o"></i>
#endif
{{ str_limit($topic_item->name, 15) }}
</a>
#endif
</li>
#endforeach
#endforeach
</ul>
</div>
<a href="#" class="btn btn-primary">
<i class="fa fa-angle-right"></i>
</a>
</div>
</div>
</div>
Example
dropdown links:
Assignment1
Assignment2
Quiz1
QUiz2
Reviewer1
If I clicked Assignment2, the left button, has the id or link to Assignment1. If I clicked Reviewer1, the right button disappears and the left button has the id or link to Quiz2 and same with the other links.

bllim / laravel4-datatables-package -> get the id from the query

I'm trying to get the ID from the query when I use edit_column but I get it only for the 'id' column, when I try to get it for the 'operations' column I get the html markup of the 'id' column.
Here is the code:
public function ajaxGetAllPages()
{
$pages = Page::select(array('id','title','updated_at','status'));
return Datatables::of($pages)
->edit_column('id', '<input type="checkbox" class="checkboxes tooltips" value="{{ $id }}" data-placement="left" data-original-title=" אינדקס # {{ $id }} " />')
->edit_column('title','{{ $title }}')
->edit_column('updated_at', '{{ date("d-m-Y | H:i",strtotime($updated_at)) }}')
->edit_column('status', '{{ $status }}')
->edit_column('operations',
'<i class="fa fa-pencil"></i>
<i class="fa fa-trash-o"></i>
<i class="fa fa-times"></i>
<div class="btn-group">
<button class="btn default btn-xs dropdown-toggle" type="button" data-toggle="dropdown">עוד <i class="fa fa-angle-down"></i></button>
<ul class="dropdown-menu pull-right" role="menu">
<li>פעולה</li>
<li>פעולה</li>
</ul>
</div>'
)
->make();
}
Markup result - http://screencast.com/t/nIefrpqc8
Am I doing something wrong or is it a bug?
Thanks,
Chen
According to Bllim docs:
If you use double quotes while giving content of add_column or edit_column, you should escape variables with backslash () else you get error. For example:
edit_column('id',"- {{ \$id }}")
Use backslash before $id.
->edit_column('operations',
'<i class="fa fa-pencil"></i>
<i class="fa fa-trash-o"></i>
<i class="fa fa-times"></i>
<div class="btn-group">
<button class="btn default btn-xs dropdown-toggle" type="button" data-toggle="dropdown">עוד <i class="fa fa-angle-down"></i></button>
<ul class="dropdown-menu pull-right" role="menu">
<li>פעולה</li>
<li>פעולה</li>
</ul>
</div>'
)

Resources