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 多表关联,之后排序