简体   繁体   English

基于Laravel多晶型一对一关系的OrderBy

[英]OrderBy on Laravel polymorph one-to-one relationship

I have problem to sort results by polymorph's table relationship. 我在按多态的表关系对结果进行排序时遇到问题。 Tried many ways, but results does not sort. 尝试了许多方法,但结果未排序。

I have looked in many threads, and final result code that I have tried looks like this: 我查看了许多线程,尝试过的最终结果代码如下所示:

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

I want to sort all rows in "adverts" table by relationship's "room" column, but nothing happens. 我想按关系的“房间”列对“广告”表中的所有行进行排序,但没有任何反应。

My tables structure is: 我的表结构是:

在此处输入图片说明 Laravel models looks like this: 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');
    }
}

UPDATE UPDATE

If I dump SQL, then I see that this code does not event run into relationship 如果我转储SQL,那么我看到此代码不会与关系发生事件

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

Also I have tried to change whereHas function to work with polymorph relationships, as Laravel does not support whereHas with polymorph relations. 我也尝试过更改whereHas具有多态关系的功能,因为Laravel不支持wherehas具有多态关系。

I have ran this code 我已经运行了这段代码

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

But it also does not sort results. 但这也不会对结果进行排序。 I had to change Laravel builder to add support for polymorph tables. 我必须更改Laravel构建器以添加对多态表的支持。

UPDATE 2 更新2

I have resolved issue and implemented code by using example provided by @Sturm answer, after applying SortBy / SortByDesc I'm manually building LengthAwarePaginator. 在应用SortBy / SortByDesc之后,我已经使用@Sturm答案提供的示例解决了问题并实现了代码,我正在手动构建LengthAwarePaginator。

But could this issue be resolved using Builder class, before calling ->get() method on my query ? 但是在对我的查询调用-> get()方法之前,可以使用Builder类解决此问题吗?

Here's something that will get you running, although I'll look for a moment more to see if there's a way to do it from Builder. 尽管我会花一会儿时间来看看是否有一种方法可以通过Builder来完成,但是这会让您运行起来。

$sorted = $adverts->sortBy(function ($val, $key) {
    return $val->advertable->rooms;
}
$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();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM