如何按关系对 laravel 处的产品进行排序?

How to sort product at laravel by relationship?

我在下面的模型页面上过滤并列出了带有代码示例的产品以及来自用户的一些数据。

我想根据价格对列出的产品进行排序。但是,正如在 minprice-maxprice 示例代码块中看到的那样,关系取决于几个条件。

从用户收到的postFrom和postTo日期组成的时间段,如果daily为0,则按照old_daily价格列出,如果daily不为0,则列出按照每日价格。

我该怎么做?

我的模型页面

public $belongsTo = [
    'price' => [
        'ac\prices\models\Price',
        'key' => 'id',
        'otherKey' => 'pro_id',
    ],
]

public static $allowedSortingOptions = array (
    'name desc' => 'Name - desc',
    'name asc' => 'Name - asc',
    'price desc' => 'Price - desc',
    'price asc' => 'Price - asc',
);

public function scopeListFrontEnd($query, $options = []){

    extract(array_merge([
        'page' => 1,
        'perPage' => 10,
        'sort' => 'created_at desc',
        'postFrom' => null,
        'postTo' => null,
        'minPrice' => null,
        'maxPrice' => null,
    ], $options));

    if(!is_array ($sort)){
        $sort = [$sort];
    }

    foreach ($sort as $_sort){
        if(in_array($_sort, array_keys(self::$allowedSortingOptions))){
            $parts = explode(' ', $_sort);

            if(count($parts) < 2){
                array_push($parts, 'desc');
            }

            list($sortField, $sortDirection) = $parts;

            $query->orderBy($sortField, $sortDirection);

        }
    }

    if($minPrice != null) {

        if(!is_array($minPrice)){
            $minPrice = [$minPrice];
        }

        foreach ($minPrice as $mnPrice){

            $query->whereHas('price', function($q) use ($mnPrice,$maxPrice,$postFrom,$postTo){
                $q->where('daily', '==', '0')
                ->where(function( $query ) use ( $mnPrice, $maxPrice ) {
                    $query->where('old_daily', '>=', $mnPrice);
                    $query->where('old_daily', '<=', $maxPrice[0]);
                });
                $q->orWhere('daily', '!=', '0')
                ->where(function( $query ) use ( $mnPrice, $maxPrice ) {
                    $query->where('daily', '>=', $mnPrice);
                    $query->where('daily', '<=', $maxPrice[0]);
                });
                $q->when($postFrom == '0', function ($sq) {
                        $sq->where('id', '>', '0');
                    }, function ($ssq) use ($postFrom, $postTo) {
                        $ssq->where(function($q) use ($postFrom) {
                            $q->whereDate('start_date', '<=', $postFrom[0])
                                ->whereDate('end_date', '>=', $postFrom[0]);
                        })->orWhere(function($q) use ($postTo) {
                            $q->whereDate('start_date', '<=', $postTo[0])
                                ->whereDate('end_date', '>=', $postTo[0]);
                        });
                        
                    });
            });

        }
    
    }

    $lastPage = $query->paginate($perPage, $page)->lastPage();

    if($lastPage < $page){
        $page = 1;
    }
    
    return $query->paginate($perPage, $page);

}

在不尝试准确解码您在这里尝试执行的操作的情况下,我将添加一个子查询 select,将 sort_price 字段拉入结果,然后您可以按 orderBy。

$query->selectRaw('CASE WHEN daily = 0 THEN old_daily ELSE daily END as sort_price');

$query->orderByRaw('(SELECT sort_price)');

如果您的结果中不需要此价格,您也可以根据 MYSQL ORDER BY CASE Issue 在排序条件中直接执行此操作。

您可以在 orderByRaw 生成器方法中执行此操作。