Laravel Yajra datatables ajax serverside slow down page load - ajax

I'm using Yajra datatables with serverside true, but page load very slow (afraid because of distinct count). I tried solution here by removing ->get() and it load faster but this causing another problem, where the input searching (smart: true) return error, not functioning. Anyone can help?
Here is my code:
$links = Link::with('owner')
->withCount(['clicks as uniqueClicks' => function($q) {
$q->select(DB::raw('count(distinct(ip_address))'));
}])
->where('account_id', $account_id)
->orderBy('created_at','desc')
->get();
return Datatables::of($links)->make();
Is it possible to optimize this code? maybe change from select raw distinct to groupBy? or do this more on eloquent way?

My mistake for not stating the full errors and in the error mentioned about laravel relationship column not found.
Here is the documentation https://yajrabox.com/docs/laravel-datatables/master/relationships
columns: [
// columns according to JSON
{ data: '' },
{ data: 'title' },
{ data: 'user_name', name: 'user.manage.name' }, <-- name = relationship column
{ data: 'link' },
{ data: 'created_at', "searchable": false },
{ data: 'action' }
],
So removing the ->get() do make your page load faster.
$links = Link::with('owner')
->withCount(['clicks as uniqueClicks' => function($q) {
$q->select(DB::raw('count(distinct(ip_address))'));
}])
->where('account_id', $account_id)
->orderBy('created_at','desc');
return Datatables::of($links)->make();

Related

Laravel filter relation's data by other relations data

I am trying to filter my tickets.tips.drawDates relation's data by other relation's column (results.draw_date) in an eager-loading query. Does anybody have any advice on how to accomplish that?
$products = Product::with([
'results' => function ($query) use ($drawDates) {
return $query->whereBetween('draw_date', $drawDates);
},
'tickets' => function ($query) use ($drawDateFrom) {
return $query->whereDate('valid_until', '>=', $drawDateFrom)->where('status', 'pending');
},
'tickets.tips',
'tickets.tips.drawDates' => function($query) {
return $query->whereNull('status')->whereDate('draw_date', 'HERE SHOULD BE draw_date COLUMN FROM results RELATION');
},
'prizes'
])->get();
You could try with the whereColumn() function, it is used to verify that two columns are equal, something like that:
return $query->whereNull('status')->whereColumn('draw_date', 'results.draw_date');

backpack crud filters by pivot table

PLease, somebody, help me with filters.
I have 3 tables: complaint, frontend_tag, frontendtags_complaints
I heed to filter complaints by frontend_tag
here is my filter code:
$this->crud->addFilter([
'name' => 'frontendtags',
'type' => 'select2',
'label'=> 'FE Tag'
], function() {
return \App\Models\FrontendTags::all()->pluck('name', 'id')->toArray();
}, function($value) {
return $this->crud->query->whereHas('frontendtags', function ($q) use ($value) {
$q->where('tag_id', $value);
});
});
here is my relation code:
public function frontendtags()
{
return $this->belongsToMany('App\Models\FrontendTags', 'frontendtags_complaints', 'complaint_id', 'tag_id');
}
The filter is not working.
Replace
$q->where('tag_id', $value);
With
$q->where('frontend_tag.id', $value);
The where condition is applied on the related table, in this case frontend_tag.

emberjs with laravel pagination

I am trying to load a paginated data, so far able to load the whole records.
Now not sure how to load the Laravel paginated data, as when I send call without pagination I get a response like
{
'users':[{
'id':1,
'name':'Aamir'
},{
'id':2,
'name':'Jamshed'
}]
}
But when I enable pagination, there is a whole bunch of data with this, and ember starts to give an error
GET http://localhost:8000/api/users?citySef=Lahore&group=Ap
200 OK
87ms
vendor.js (line 9861)
WARNING: Encountered "total" in payload, but no model was found for model name "total"
This has to be fixed on the laravel end,
$city = blood_cities::where('sef' , '=', [$citySef])->get();
$users = blood_users::where('city_id', '=',$city[0]->id)
->where( 'group', '=', $group )
->paginate(15);
$return = array(
'users' => $users->items(),
'meta'=> array(
'total'=>$users->total(),
'current_page'=>$users->currentPage(),
)
);
return $return;
now ember will not give errors we will get the result.
Update: 2015-05-25
able to create pagination from http://blog.ksol.fr/paginated-apis-with-ember-js/

Datatables using laravel-datatables-oracle getting Ajax error

I am using http://datatables.net/and https://github.com/yajra/laravel-datatables-oracle. When I try search I get a popup with an "Ajax error" I seemed to have narrowed it down to being an issue when ever there is a join in the query.
Here is method used for the Ajax request (removed fields for simplicity):
$leads = Lead::leftJoin('lead_status', 'leads.status', '=', 'lead_status.id')
->select('leads.id', 'leads.email', 'lead_status.status');
This works fine as I said it is only when I try search do I get the error, I don't get it when sorting or paging through results.
When there is no join in the query then I don't get any issues.
Been on this for a while now and not sure what to do..
When using a join statement, you have to specify in js the fully qualified name of field. You should use table.column pattern. See example code below:
$('#posts-table').DataTable({
processing: true,
serverSide: true,
ajax: 'joins-data',
columns: [
{data: 'id', name: 'posts.id'},
{data: 'title', name: 'posts.title'},
{data: 'name', name: 'users.name'},
{data: 'created_at', name: 'posts.created_at'},
{data: 'updated_at', name: 'posts.updated_at'}
]
});
And on your controller
public function getJoinsData()
{
$posts = Post::join('users', 'posts.user_id', '=', 'users.id')
->select(['posts.id', 'posts.title', 'users.name', 'users.email', 'posts.created_at', 'posts.updated_at']);
return Datatables::of($posts)
->editColumn('title', '{!! str_limit($title, 60) !!}')
->editColumn('name', function ($model) {
return \HTML::mailto($model->email, $model->name);
})
->make(true);
}

Select only certain columns in related model when eager loading

I have two related models:
class Attribute extends Eloquent
{
public function categories()
{
return $this->hasMany('Category');
}
}
class Category extends Eloquent
{
public function attributes()
{
return $this->belongsTo('Attribute');
}
}
I want to return all attributes and their categories as a JSON object, but I only want to select certain fields in both models (i.e. not return fields like 'created_at' in the JSON).
I've tried this:
$attributes = Attribute::select('id', 'name')
->with(['categories' => function ($query) {
$query->select('categories.id', 'categories.name', 'categories.attribute_id');
}]);
Response::JSON($attributes->get());
but despite the select query for the related model, unrequested fields are returned:
attributes: [{
id: 3,
name: "Organisation",
categories: [{
id: 3,
name: "Asia HQ",
attribute_id: 3,
created_at: "2013-11-30 00:00:00",
updated_at: "2013-11-30 00:00:00"
}]
}]
How do I select only certain columns in related model when eager loading?
What about an eloquent method that will look like this?
public function dynamicAttributes($array_columns) {
return $this->belongs_to('User')->select((array) $array_comuns);
}
Where $array_columns could be a string or array of strings representing a columns you want?
Make use of select() laravel method:
$attributes = Attribute::select('id', 'name')->with(['categories' =>function($query){
$query->select(['categories.id', 'categories.name','categories.attribute_id'])->get();
}]);
Response::JSON($attributes->get());
To make select method work in eager loading you need to include foreign_key in
selected column list.
Reference : http://laravel-tricks.com/tricks/column-selection-in-eager-loading
If you want to always return those specific fields from the categories relation, defining the select in the relationship will work, but if you would like to do it on the fly for one specific query, ask Eloquent to only return those fields.
$attributes = Attribute::with(['categories' => function ($query) {
$query->select('id', 'name', 'attribute_id');
}])->get('id', 'name');
... Or you could use Fluent
DB::table('attributes')
->join('categories', 'attributes.id', '=', 'categories.attribute_id')
->select('attributes.id', 'attributes.name', 'categories.id', 'categories.name', 'categories.attribute_id')
->get();
Try this:
$attributes = Attribute::select('id', 'name')
->with([
'categories:categories.id,categories.name,categories.attribute_id',
]);
Response::JSON($attributes->get());
Please notice: no space after comma in argument list

Resources