Perform order by relationship field in Eloquent
This will sort the subquery. Not the "first query (the product query)".
Basically, your subquery will be:select * from variants where product_id in (....) order by price
, and that is not what you want, right?
<?php
// ...
$order = $request->sort;
$products = Product::whereHas('variants')->with(['reviews', 'variants' => function($query) use ($order) {
if ($order == 'price') {
$query->orderBy('price');
}
}])->paginate(20);
If you want to sort product +/or variant you need to use join.
$query = Product::select([
'products.*',
'variants.price',
'variants.product_id'
])->join('variants', 'products.id', '=', 'variants.product_id');
if ($order == 'new') {
$query->orderBy('products.created_at', 'DESC');
} else if ($order == 'price') {
$query->orderBy('variants.price');
}
return $query->paginate(20);
How can i sort an laravel eloquent query by one-to-many relation
I solved this problem:
First off all add a hasOne relation to Product model:
public function latestInventory()
{
return $this->hasOne(Inventory::class);
}
Then in ProductController:
$products = Product::with(['latestInventory' => function($query) {
$query->where('count', '>', 0)->orderBy('id');
}]);
$products = $products->get();
$products = $products->sortBy('latestInventory.price')->paginate(16);
return $products->values()->toArray();
For Paginate the collection :
In ASP (AppServiceProvider.php) on boot method:
Collection::macro('paginate', function($perPage, $total = null, $page = null, $pageName = 'page') {
$page = $page ?: LengthAwarePaginator::resolveCurrentPage($pageName);
return new LengthAwarePaginator(
$this->forPage($page, $perPage),
$total ?: $this->count(),
$perPage,
$page,
[
'path' => LengthAwarePaginator::resolveCurrentPath(),
'pageName' => $pageName,
]
);
});
In app/Support/Collection.php:
<?php
namespace App\Support;
use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Support\Collection as BaseCollection;
class Collection extends BaseCollection
{
public function paginate($perPage, $total = null, $page = null, $pageName = 'page')
{
$page = $page ?: LengthAwarePaginator::resolveCurrentPage($pageName);
return new LengthAwarePaginator(
$this->forPage($page, $perPage),
$total ?: $this->count(),
$perPage,
$page,
[
'path' => LengthAwarePaginator::resolveCurrentPath(),
'pageName' => $pageName,
]
);
}
}
Related Topics
Wordpress Woocommerce - Use Update_Post_Meta to Add Product Attributes
Can't Insert Russian Text into MySQL Database
Boolean Variables Posted Through Ajax Being Treated as Strings in Server Side
How to Escape String from PHP for JavaScript
How to Eliminate PHP5 Strict Standards Errors
How to Swap Colors in Image Using Gd Library in PHP
Laravel: General Error: 1615 Prepared Statement Needs to Be Re-Prepared
Execute Two Shell Commands in Single Exec PHP Statement
Replace Add to Cart Button with a Read More Linked to Product Page on Shop Pages in Woocommerce 3
Compile Error: "G++: Error Trying to Exec 'Cc1Plus': Execvp: No Such File or Directory"
Troubleshooting "The Use Statement with Non-Compound Name ... Has No Effect"
How to Reset MySQL Pointer Back to the First Row in PHP
Google API How to Connect to Receive Values from Spreadsheet
What Is Difference of Developing a Website in MVC and 3-Tier or N-Tier Architecture