i need pagination with sortBy in laravel - laravel

I have 3 tables products, prices, cats.
I need to filter product by cats and sort by price but I have a problem:
this code work very well but needs pagination.
$products = Product::with('photo', 'price', 'brand')
->whereHas('cats', function ($q) use ($cat) {
$q->where('cat_id', $cat->id);
})
->get()
->sortByDesc(function($query) {
return $query->price->price;
});
at first I did it like this:
$products = Product::with('photo', 'price', 'brand')
->whereHas('cats', function ($q) use ($cat) {
$q->where('cat_id', $cat->id);
})
->paginate($page)
->sortByDesc(function ($query) {
return $query->price->price;
});
but links() did not work.
After i did it like this:
$products = Product::with('photo', 'price', 'brand')
->whereHas('cats', function ($q) use ($cat){
$q->where('cat_id', $cat->id);
})
->paginate($page);
$products->setCollection(
$products->sortBy(function ($query) {
return $query->price->id;
})
);
but sortBy does not work.
so I can't use orderBy() by join prices table
because when I do it I can show all products and I can't filter product by categories
my mind does not work, if someone can to help me, I will be very grateful

I believe you can also do:
Product::join('price', 'price.id', '=', 'photo.price_id')
->orderBy('price.price', 'asc')
->select('photo.*')
->paginate(10);

Related

retrieve simple products and product_variation with corcel

In larvel I'm using corcel and with the help of this comment I'm trying to retrieve only simple products and variations of variable products.
$type = array('product_variation','product');
$status = 'publish';
$posts =
\Corcel\Model\Post::
type($type)->
whereHas('taxonomies', function($q) {
$q->where('taxonomy', 'product_type')
->whereHas('term', function($q) {
$q->where('slug', 'simple');
})
// since variations have no product_type taxonomy, then
->orwhere('taxonomy','<>', 'product_type');
})->
status($status)->
latest()->
limit(500)->
get();
return $posts;
but it only returns product_variation(s), and no simple product. can some one please explain my wrong doing?
i had the same problem, i realized that i can use doesntHave
$posts = \Corcel\Model\Post::status('publish')
->whereIn('post_type', ['product_variation','product'] )
->doesntHave('taxonomies')
->orWhereHas('taxonomies', function ($query) {
$query->whereIn('taxonomy',['product_type'])
->whereHas('term', function($q) {
$q->where('slug', 'simple');
});
})
->latest()
->limit(50)
->get();
return $posts;

Spatie Query Builder filter nested relations

Using Spatie Query Builder I would like to extend the filters on nested relationships
The following code fetches locations with the relation jobs counts which works fine. I would like to extend the filter on job relation to can query relation job.level which is a many to many. How would I go for?
the filter would look like /options/?filter[job.level]=2
Germany - 12,
Italy - 34
$locations = QueryBuilder::for(JobLocation::class)
->select('id as value', 'title', 'country_id')
->orderBy('title')
->withCount(['job as counts' => function ($q) {
$q->whereNull('deleted_at');
}])
->whereHas('country', function ($q) {
$q->where('id', '=', 80);
})
->allowedAppends(
'job',
)
->allowedIncludes('job', 'job.level',)
->allowedFilters([
AllowedFilter::exact('job.language_id'),
AllowedFilter::exact('job.level', 'job.level.id')
])->get();
I think you are looking for the whereHas function. See the docs for querying relation existence here. But you are already doing this for the country relationship, this is not any different.
So I think yours would look something like:
$locations = QueryBuilder::for(JobLocation::class)
->select('id as value', 'title', 'country_id')
->orderBy('title')
->withCount(['job as counts' => function ($q) {
$q->whereNull('deleted_at');
}])
->whereHas('country', function ($q) {
$q->where('id', '=', 80);
})
//New query constraint here
->whereHas('job', function ($q) {
$q->where('level', '=', 2);
})
->allowedAppends(
'job',
)
->allowedIncludes('job', 'job.level',)
->allowedFilters([
AllowedFilter::exact('job.language_id'),
AllowedFilter::exact('job.level', 'job.level.id')
])->get();

Laravel remove parent if related collection

I have a model with a related collection
now im doing this query
$data = DeliveryPartner::when($filter, function ($q) use ($request) {
})
->with(['orders' => function ($query) {
$query
->where('delivery_partner_invoice_id', '=', '')
->orWhereNull('delivery_partner_invoice_id')
->whereIn('status', ['payment-accepted', 'completed', 'full-refund', 'partial-refund']);
}])->get();
Now i am wondering. If the orders returns empty is it posible to remove this parent from the collection?
I Know i can do this after the eloquent query with a loop. But is it possible to do this in the query?
we cant completely remove that parent ( with index ) BUT you can set those to null using transform() like this;
$data = DeliveryPartner::when($filter, function ($q) use ($request) {
})
->with(['orders' => function ($query) {
$query
->where('delivery_partner_invoice_id', '=', '')
->orWhereNull('delivery_partner_invoice_id')
->whereIn('status', ['payment-accepted', 'completed', 'full-refund', 'partial-refund']);
}])->get()->transform(function($item){
if(!$item->orders->count() ){
return;
}
return $item;
});
Note: this will not completely remove those parents but it will set them to empty.

Laravel select only categories wherein product ids

Hi i have a categories and products table with one to many relation. I want to select categories with products which are in product_ids(which it will get from other query). I tried
$categories = Category::with(['products' => function ($query) use($product_ids) {
$query->whereIn('id', $product_ids);
}])
->get();
the above query will select all the categories even if the product not in product_ids ( empty array if not in produc_id) but i just want to select those categories which has the products in the product_ids.please help
I just Solved it by adding whereHas
$categories = Category::with(['products' => function ($query) use($product_ids) {
$query->whereIn('id', $product_ids);
}])
->whereHas('products', function ($q) use($product_ids) {
$q->whereIn('id', $product_ids);
})
->get();
Use whereHas
$categories = Category::whereHas('products', function ($query) use($product_ids) {
$query->whereIn('id', $product_ids);
})
->get();

Laravel 4 Eager Loading constraints

I want to get all Items (topics) WITH their comments, if comments user_id = $id. I try something like this, but it isn't working. So if Item hasn't got any comment with user_id = $id, then I don't need this Item.
In DiscussionsItem model I have methode:
public function discussionsComments() {
return $this->hasMany('DiscussionsComment', 'discussionsitem_id');
}
My query in controller is like this:
$items = DiscussionsItem::whereBrandId($brand_id)
->whereBrandCountryId($country_id)
->with(['discussionsComments' => function($query) use ($id) {
$query->where('user_id', '=', $id);
}])
->whereHas('discussionsComments', function($query) use ($id) {
$query->where('user_id', '=', $id);
})
->with(['views' => function($query) use ($id) {
$query->where('user_id', $id)->count();
}])
->orderBy('created_at', 'DESC')->get();
My problem is that I get items with comments, where comments user_id != $id.
P.S. I need to take 5 comments, but I cant imagine how to do that, because ->take(5) in my eager load is not working.
You can do a custom scope, or just limit the amount returned by your relation:
public function discussionsComments() {
return $this->hasMany('DiscussionsComment', 'discussionsitem_id')
->latest()
->take(5);
}

Resources