OrderBy与Laravel的多态一对一关系

时间:2016-01-15 15:34:10

标签: php mysql laravel eloquent

我有问题按照多态的表关系对结果进行排序。 尝试了很多方法,但结果并没有排序。

我已查看了很多线程,我尝试过的最终结果代码如下所示:

return \App\Models\Advert::with(['advertable' => function ($query) {
    $query->orderBy('rooms', 'DESC');
}])->get();

我想对"广告"中的所有行进行排序按关系表"房间"专栏,但没有任何反应。

我的表结构是:

enter image description here Laravel模型看起来像这样:

<?php
// Main "adverts" polymorph table with advertable_id and advertable_type
class Advert extends \Illuminate\Database\Eloquent\Model
{
    /**
     * @return \Illuminate\Database\Eloquent\Relations\MorphTo
     */
    public function advertable()
    {
        return $this->morphTo();
    }
}

// "advert_flats" table
class Flat extends \Illuminate\Database\Eloquent\Model
{
    /**
     * @return \Illuminate\Database\Eloquent\Relations\MorphOne
     */
    public function advert()
    {
        return $this->morphOne(\App\Models\Advert::class, 'advertable');
    }
}

// "advert_homes" table
class Home extends \Illuminate\Database\Eloquent\Model
{
    /**
     * @return \Illuminate\Database\Eloquent\Relations\MorphOne
     */
    public function advert()
    {
        return $this->morphOne(\App\Models\Advert::class, 'advertable');
    }
}

更新

如果我转储SQL,那么我看到这段代码没有事件进入关系

select * from `adverts` where `category_id` = 2 and `adverts`.`deleted_at` is null

此外,我尝试更改whereHas函数以使用多态关系,因为Laravel不支持whereHas与多态关系。

我已经运行了这段代码

return $model->whereHas('advertable', function ($q) {
   $q->orderBy('rooms', 'DESC');
}, '>=', 1, ['\App\Models\Flat']);

但它也没有对结果进行排序。 我不得不更改Laravel构建器以添加对多态表的支持。

更新2

我已经使用@Sturm answer提供的示例解决了问题并实现了代码,应用了SortBy / SortByDesc后我手动构建了LengthAwarePaginator。

但在我的查询中调用 - &gt; get()方法之前,是否可以使用Builder类解决此问题?

2 个答案:

答案 0 :(得分:1)

这里有一些可以让你跑步的东西,虽然我会更多地看一下,看看是否有办法从Builder中做到这一点。

$sorted = $adverts->sortBy(function ($val, $key) {
    return $val->advertable->rooms;
}

答案 1 :(得分:0)

$adverts = \App\Models\Advert::query()->select(
        DB::raw('
            adverts.*, 
            CASE 
                WHEN adverts.advertable_type like(\'%Flat\') THEN advert_flats.rooms 
                WHEN adverts.advertable_type like(\'%Home\') THEN advert_homes.rooms 
            END
            as rooms 
        ')
    )->leftJoin(
        "advert_flats",
        function ($join) {
            /** @var \Illuminate\Database\Query\JoinClause $join */
            $join->on('adverts.advertable_id', '=', "advert_flats.id")
                ->where('adverts.advertable_type', 'like', '%Flat');
        }
    )->leftJoin(
        "advert_homes",
        function ($join) {
            /** @var \Illuminate\Database\Query\JoinClause $join */
            $join->on('adverts.advertable_id', '=', "advert_homes.id")
                ->where('adverts.advertable_type', 'like', '%Home');
        }
    )->orderBy('rooms', 'ASC')->get();