Paginate based on conditional with relationship - laravel

I'm trying to paginate based on a conditional on a relationship. Thought this would work but it does not..
Product::with(['manufacturer' => function($query){
$query->where('name', '=', 'Maker');
}])->paginate(10)->toArray();
for some reason It only works on the first model. I can tell because its the only one loading the manufacturer data.
Anyone have any idea how to do this?
thanks!

Laravel offers convenient way to query relationships (docs)
I think, this is what you want
$products = Product::whereHas('manufacturer', function($q)
{
$q->where('name', '=', 'Maker');
})->get();
You may add pagination and other things as you wish.

Related

Product filtering problems with Laravel Query Builder

I try to implement ajax based filtering in my ecommerce project homepage for searching a product. I am using Laravel Query Builder. My Query for filtering products is given below-
$result= DB::table('products')
->leftjoin('products_description','products.products_id','products_description.products_id')
->leftjoin('image_categories', 'products.products_image', '=', 'image_categories.image_id')
->leftjoin('products_to_categories','products.products_id','products_to_categories.products_id')
->leftjoin('categories','products_to_categories.categories_id','categories.categories_id')
->when($category_slug, function($q) use ($category_slug) {
return $q->where('categories.categories_slug', $category_slug);
})
->where('products_name','like',"%{$querval}%")
->where('image_categories.image_type','=','ACTUAL')
->orderby('products.products_id','DESC')
->take(5)
->get();
I get every product twice in search result. don't know why. A sample response is given in this picture.
Can anyone help me to optimize my query for getting the desired result?
join with categories table only when you have to.
and select your columns strictly. then group by selected columns.
$result= DB::table('products')
->leftjoin('products_description','products.products_id','products_description.products_id')
->leftjoin('image_categories', 'products.products_image', '=', 'image_categories.image_id')
->when($category_slug, function($q) use ($category_slug) {
return $q->leftjoin('products_to_categories','products.products_id','products_to_categories.products_id')
->leftjoin('categories','products_to_categories.categories_id','categories.categories_id')
->where('categories.categories_slug', $category_slug);
})
->where('products_name','like',"%{$querval}%")
->where('image_categories.image_type','=','ACTUAL')
->orderby('products.products_id','DESC')
->select(['products_name','products.id','image_path'])
->groupBy(['products_name','products.id','image_path'])
->take(5)
->get();
you can use from groupBy to avoid comming repeated data.
try this one:
$result= DB::table('products')
->leftjoin('products_description','products.products_id','products_description.products_id')
->leftjoin('image_categories', 'products.products_image', '=', 'image_categories.image_id')
->when($category_slug, function($q) use ($category_slug) {
return $q->where('categories.categories_slug', $category_slug);
})
->where('products_name','like',"%{$querval}%")
->where('image_categories.image_type','=','ACTUAL')
->orderby('products.products_id','DESC')
->groupBy('products_name','products.products_id')
->take(5)
->get();

How to fetch latest posts and specific post id at first in laravel eloquent

Is there way to fetch latest posts with pagination And I also want a specific post to first position in returned collection.
I tried this...
Post::where(function ($query) {
$query->where('status', 'draft')->orWhere('status', 'published');
})
->orWhere('id', 21)
->with(['author.profile'])
->orderBy('created_at', 'desc')
->paginate(3);
In this query I do get the 21 post id but it is on 3rd page. I want to get it on first place. Please guide How can I do this.
Thanks
You can achieve this by using a raw statement in your orderBy
Post::orderBy(DB::raw('id = 5'), 'DESC')
->orderBy('created_at', 'desc')
This is because mysql can use boolean expressions in order by statements
By using eloquent you do like this
Post::where('id', '=', 21)->orderBy('created_at','desc')->first();

Where clause inside whereHas being ignored in Eloquent

Im trying to make a query using whereHas with eloquent. The query is like this:
$projects = Project::whereHas('investments', function($q) {
$q->where('status','=','paid');
})
->with('investments')
->get();
Im using Laravel 5.2 using a Postgres driver.
The Project model is:
public function investments()
{
return $this->hasMany('App\Investment');
}
The investments model has:
public function project() {
return $this->belongsTo('App\Project');
}
The projects table has fields id,fields...
The investments table has the fields id,project_id,status,created_at
My issue is that the query runs and returns a collection of the projects which have at least one investment, however the where clause inside the whereHas is ignored, because the resulting collection includes investments with status values different than paid.
Does anyone has any idea of what is going on?
I believe this is what you need
$projects = Project::whereHas('investments', function($q) {
$q->where('status','=','paid');
})->with(['investments' => function($q) {
$q->where('status','=','paid');
}])->get();
whereHas wil check all projects that have paid investments, with will eagerload all those investments.
You're confusing whereHas and with.
The with method will let you load the relationship only if the query returns true.
The whereHas method will let you get only the models which have the relationship which returns true to the query.
So you need to only use with and not mix with with whereHas:
$projects = Project::with(['investments' =>
function($query){ $query->where('status','=','paid'); }])
->get();
Try like this:
$projects = Project::with('investments')->whereHas('investments', function($q) {
$q->where('status','like','paid'); //strings are compared with wildcards.
})
->get();
Change the order. Use with() before the whereHas(). I had a similar problem few weeks ago. Btw, is the only real difference between the problem and the functional example that you made.

How to use '::whereHas()' as a constraint for '::with()' query when using Eloquent?

I have a query:
Posts::whereHas('comments', function($query){
$query->where('name', 'like', 'asd');
})->with('comments')->get();
It returns all posts that have comments which have name like 'asd' with all comments of these posts. Can I use the above constraint in '::whereHas' for the 'with' method, so it would not return all comments, but only those that match the requirements? Or do I have to duplicate the query?
You can create query something like this, almost without duplicate :)
$callback = function($query) {
$query->where('name', 'like', 'asd');
}
Posts::whereHas('comments', $callback)->with(['comments' => $callback])->get();
Or, you can make like in this post Laravel - is there a way to combine whereHas and with

How to select instances for specific 'n' on m:n relationships?

I have two models Teacher and Category. These two have Many to Many relationship.
I want to get those teachers who have one category equal to "OLevels". Which method of eloquent is used for it or is there any other way I can get it?
Is there anyway to get it as:
$teachers = Teacher::where('category', '=', 'OLevels')->get();
You can use whereHas for that:
$category = 'OLevels';
$teachers = Teacher::whereHas('category', function($q) use ($category){
$q->where('name', $category);
})->get();
You could make use of eager loading with constraints
$teachers = Teacher::with(['category' => function($query)
{
$query->where('category', '=', 'OLevels');
}])->get();
Further info in the documentation.

Resources