我尝试从shop_products
表格pinned
列shop_products_options
列对产品进行排序:
$products = Shop\Product::with(['options' => function ($query) {
$query->orderBy('pinned', 'desc');
}])->paginate(5);
我在Shop \ Product model中设置了关系:
public function options()
{
return $this->hasOne('Shop\Options');
}
但产品没有排序。我得到的查询仅适用于shop_products_options
表。
SELECT * FROM `shop_products_options` WHERE `shop_products_options`.`product_id` in ('8', '9', '10', '11', '12') ORDER BY `pinned` DESC
如何解决?
答案 0 :(得分:65)
预先加载使用单独的查询,因此您需要加入:
$products = Shop\Product::join('shop_products_options as po', 'po.product_id', '=', 'products.id')
->orderBy('po.pinned', 'desc')
->select('products.*') // just to avoid fetching anything from joined table
->with('options') // if you need options data anyway
->paginate(5);
SELECT
子句是为了不将加入的列附加到您的Product
模型。
编辑:根据@alexw注释 - 如果需要,您仍然可以包含已连接表中的列。您可以将其添加到select
或致电addSelect/selectRaw
等。
答案 1 :(得分:9)
您无法按相关表格列进行排序,而无需手动加入相关表格。 Jarek的答案是正确的,但这可能真的很尴尬:
1.第一个问题是你需要担心选择。
->select('products.*')
原因:没有来自shop_products_options的select()id可以选择并融入产品模型。
2.第二个问题是你需要担心groupBy。
->groupBy('products .id');
原因:如果关系是HasOne并且产品有多个shop_products_options,则查询将返回更多产品行。
3.第三个问题是你需要改变所有其他where子句:
->where('date', $date)
到
->where('products .date', $date)
原因:产品和shop_products_options都有" date"属性,在这种情况下,没有用表格选择属性"模糊列"错误将被抛出。
4.第四个问题是你使用的是表名(而非模型),这也很糟糕而且很尴尬。
->where('products.date', $date)
5.第五个问题是你需要担心连接表的软删除。如果shop_products_options使用SoftDeletes特征,则必须添加:
->where('shop_products_options .deleted_at', '=', null)
以上所有问题都非常令人沮丧,加入雄辩的表可能会给你的代码带来很多问题。我创建了一个解决上述所有问题的包,你可以通过关系属性以优雅的方式排序,对于你的情况,它将是:
$products = Shop\Product::orderByJoin('options.pinned', 'desc')->paginate(5);
答案 2 :(得分:1)
+6 Laravel 版本还有另一种方式 Subquery Ordering:
.click()