I've followed the instructions on the Laravel documentation for pagination with appends([]) however I'm having a little trouble with the persistence of these parameters.
Say for example, I pass home?category=Cars&make=Tesla to my view. What is the best way to paginate with them Get requests?
Right now I've passed the category as a parameter to the view as (where category is the model i've grabbed findOrFail with the request('category');)
$category_name = $category_model->name;
And then in my view it's like so:
{{ $vehicles->appends(['category' => $category_name])->links() }}
But when I go between pages in the pagination, this $category_name value doesn't seem to persist. Whats the recommended way to achieve what I want?
Thanks.
You can append the query string in your controller when you paginate the result. I'm not sure if that was your only question or even regarding applying the query string as a condition. So here is a sample showing you how to do both. This should give you an idea of how to do it. I just assumed the column names in this example.
$category = request('category');
$make = request('make');
$vehicles = Vehicle::when($category, function ($query) use ($category) {
return $query->where('category', $category);
})
->when($make, function ($query) use ($make) {
return $query->where('make', $make);
})
->paginate(10);
$vehicles->appends(request()->query());
return view('someview', compact('vehicles'));
Related
Method Illuminate\Database\Eloquent\Collection::withQueryString does
not exist.
when i write this code it gives this error
blade;
<div class="float-right">{{ $modeller->withQueryString()->links()}}</div>
controller;
public function index(){
$modeller = Modeller::query();
$koleksiyonlar = Koleksiyon::all();
$modelistler = Modelist::all();
$uretim_sorumlulari = Uretim_sorumlusu::all();
if(request('model_kodu')){
$modeller = $modeller->where('ModelKodu', 'LIKE', "%".request('model_kodu')."%");
}
if(request('koleksiyon_id')){
$modeller = $modeller->where('koleksiyon_id', 'LIKE', "%".request('koleksiyon_id')."%");
}
if(request('uretim_sorumlusu_id')){
$modeller = $modeller->where('UretimSor', 'LIKE', "%".request('uretim_sorumlusu_id')."%");
}if(request('modelist_id')){
$modeller = $modeller->where('modelist_id', 'LIKE', "%".request('modelist_id')."%");
}
$modeller = $modeller->paginate(18);
return view('kumas.index',compact('modeller','koleksiyonlar','modelistler','uretim_sorumlulari'));
}
The paginate method, runs an implicit get on your query result.
try to use withQueryString instead of paginate.
example:
$modeller->withQueryString()->paginate(18);
but from your use case I suggest to use this in your view, instead of query string, this will add everything came from query string to your links:
{{ $users->appends($_GET)->links() }}
More Details on the pagination & Query String params
the page, offset, ... and everything paginate needs, would append automatically to paginate function without any effort.
you only need to explicitly ->appends($_GET) when you have some filtering parameters in your $_GET and want to preserve them in the following requests, when user clicks the next page or previous page
to expand on #Abilogos answer, I think it is better to use Request::except('page') method, which return an array of query parameter except the page parameter
in your blade view:
{{ $users->appends(\Request::except('page')->links() }}
I have posts table that has related table where I store different translations based on post_id now when I want to return translation data based on user selected locale it says:
mb_strpos(): Argument #1 ($haystack) must be of type string, Closure given
Here is my function
$posts = Post::with('translations', function($q) {
$q->where('translate_code', app()->getLocale());
})->get();
dd($posts); // returning error above
But if I do this
$posts = Post::with('translations')->get();
dd($posts);
I will get following results
Here is translations data details:
My question is:
How can I return the one translation that has current locale name only?
If you using callback in with then use array of relations like below. Older version of laravel was working which you mentioned but latest version need array of relations when using callback.
$posts = Post::with(['translations'=> function($q) {
$q->where('translate_code', app()->getLocale());
}])->get();
using conditional eager loading should be like this:
$posts = Post::with(['translations'=> function($q) {
$q->where('translate_code', app()->getLocale());
}])->get();
while the relation name is the key, a closer to get data should be the value for the associative array for 'with' statement.
You can query your relation by using whereHas().
Docs: Laravel Docs Relationships
For example:
$posts = Post::whereHas('translations', function ($query) {
$query->where('translate_code', 'en');
})->get();
Maybe try to put the app()->getLocale() into a variable first. (after trying this out in tinker, this does seem te return a string, so may passing it by reference might help).
I have collection that created with complicated laravel query and this query's result is too big. So i think i must use algolia. As i know, algolia gets the model table data to itself as json and serve from there.
$result = User::search("UserName")->get();
It needs to some model configurations like searchAs etc.. all are related with existing model and you can make search from model with search method (above example). What i want to ask is, i have complicated query and result has too many attributes that come from another tables (joined). I want to make search on my custom query result. Is it possible ?
My example query :
$friendShips = Friend::
join("vp_users as users","users.id","=","friendships.friendID")
->leftJoin("vp_friendships as friendshipsForFriend",function($join) use ($request)
{
$join->on("friendships.friendID","=","friendshipsForFriend.userID");
$join->on("friendshipsForFriend.friendID","=",DB::raw($request->userID));
})
->leftJoin("vp_videos_friends as videosFromFriendMedias",function($join)
{
$join->on("videosFromFriendMedias.userID","=","friendships.friendID");
$join->on("videosFromFriendMedias.friendID", "=" ,"friendships.userID");
$join->on("videosFromFriendMedias.isCalled", "=" , DB::raw(self::CALLED));
})
->leftJoin("vp_videos_friends as videosToFriendMedias",function($join)
{
$join->on("videosToFriendMedias.userID", '=', "friendships.userID");
$join->on("videosToFriendMedias.friendID", '=', "friendships.friendID");
$join->on(function($join){
$join->on("videosToFriendMedias.isCalled", '=', DB::raw(self::CALLED));
$join->orOn("videosToFriendMedias.isActive", '=', DB::raw(self::ACTIVE));
});
})
->leftJoin("vp_videos_friends as
//some join rules too
})...
I believe the best way would be to use this request and chain the searchable() method. It will index the collection returned by the query to Algolia.
$friendShips = Friend::
join("vp_users as users","users.id","=","friendships.friendID")
->leftJoin("vp_friendships as friendshipsForFriend",function($join) use ($request) {
$join->on("friendships.friendID","=","friendshipsForFriend.userID");
$join->on("friendshipsForFriend.friendID","=",DB::raw($request->userID));
})
->searchable();
I'm making a query using the following line:
$items = $this->model->with('subCategory')->get();
But I want to put a query inside the with() method, because I just want to get the items from with() where the status is equal to 0.
How can I achieve this?
There is an "eager loading" in L5 documentation. Here
$items = $this->model->with(['subCategory' => function ($query) {
$query->where('status', 0); }])->get();
These are called eagarload constraints, you can achieve your result using a closure
For example
$items = $this->model->with(['subCategory'=>function($q){
$q->whereId('5');
//or any other valid query builder method.
}])->get();
Let me know how you get on.
I have a table called List which i planned to be displayed into view with this command : $lists= List::with('user', 'product.photodb', 'tagCloud.tagDetail')->get();. But, i want the data displayed is only those that has TagID equal to the one user inputted. Those data can be retrieved from TagCloud table.
What i am currently doing is :
$clouds = TagCloud::select('contentID')
->where('tagDetailID', '=', $tagID)
->get();
$lists = List::with('user', 'product.photodb', 'tagCloud.tagDetail')
->where('id', '=', $clouds->contentID)
->get();
But when i tried to run it, it only return a null value, even though when i am doing return $clouds, it does returned the desired ID.
Where did i do wrong ? Any help is appreciated !
A couple of gotchas with your current solution.
Using get() returns an Illuminate\Database\Eloquent\Collection object. Hence you can't use $clouds->contentID directly since $clouds is a collection (or array if you prefer). See Collection Documentation.
where(...) expects the third parameter to be a string or integer, aka single value. Instead, you are passing a collection, which won't work.
The correct way is to use whereHas() which allows you to filter through an eager loaded relationship.
Final Code:
$lists = List::with('user', 'product.photodb', 'tagCloud.tagDetail')
->whereHas('tagCloud',function($query) use ($tagID) {
return $query->where('contentID','=',$tagID);
})
->get();
See WhereHas Documentation.
What you want is whereHas()
$list = List::with(...)
->whereHas('relation', function($q) use($id) {
return $q->where('id', $id);
})->get();
Apply Where condition in you tagCloud model method tagDetail
public function tagDetail(){
return $q->where('id', $id);
}