Laravel 多态关联中利用关联表相关字段进行排序的问题

1 目标

1.1 在 Laravel 项目的开发中,多态的需求很常见,按多态关联进行排序的需求也是必须的。

1.2 请想像,我们有一个需求,荣誉栏目多态关联一个档案模型,要求在荣誉中按档案的推荐时间进行排序,以获取最近推荐内容的前5条。

2 测试

2.1 Honour

<?php

namespace App;

use AppTraitsHasArchive;
use IlluminateDatabaseEloquentModel;

class Honour extends BaseModel
{
    use HasArchive;
    
    protected static function boot()
    {
        parent::boot();
        static::created(function ($honour) {
            info(__CLASS__ . __METHOD__);
        });
    }
    
}

2.2 HasArchive

<?php


namespace AppTraits;


use AppArchive;

trait HasArchive
{
    /**
     * The boot method.
     */
    public static function bootHasArchive()
    {
        /**
         * Handle the "deleting" event.
         */
        static::deleting(function ($model) {
            $class = get_class($model);
            info("HasArchive Trait deleting {$class} {$model->id}");
            if ($archive = $model->archive) {
                $archive->delete();
            }
        });
        
        static::created(function ($model) {
            info(__CLASS__ . __METHOD__);
        });
        
    }
    
    /**
     * Model has an archive.
     *
     * @return mixed
     */
    public function archive()
    {
        return $this->morphOne(Archive::class, 'model_has_archive');
    }
    
    /**
     * Scope of params.
     *
     * @param $query
     * @param array $params
     * @return mixed
     */
    public function scopeOfParams($query, $params = [])
    {
        $field   = null;
        $keyword = null;
        $sort    = null;
        $order   = null;
        extract($params);
        $class = $this->getMorphClass();
        $table = $this->getTable();
        $query->leftJoin('archives', 'archives.model_has_archive_id', '=', "{$table}.id")
            ->where('archives.model_has_archive_type', $class)
            ->select(["{$table}.*"]);
        if ($keyword) {
            if ($field) {
                $query->where(function ($query) use ($field, $keyword) {
                    $query->orWhere($field, 'regexp', $keyword);
                });
            } else {
                $query->where(function ($query) use ($keyword) {
                    foreach (['archives.title', 'archives.title_pinyin'] as $field) {
                        $query->orWhere($field, 'regexp', $keyword);
                    }
                });
            }
        }
        if ($sort && $order) {
            $query->orderBy($sort, $order);
        }
        return $query;
    }
    
    /**
     * Scope recommended.
     *
     * @param $query
     * @return mixed
     */
    public function scopeRecommended($query)
    {
        return $query->whereHas('archive', function ($query) {
            return $query->recommended();
        });
    }
    
    
}

2.3 测试通过

3 结论

3.1 可以通过 leftJoin 多表关联,之后排序

原文地址:https://www.cnblogs.com/mouseleo/p/10982472.html