【问题标题】:Laravel Eloquent Polymorphic Scope latest first itemLaravel Eloquent Polymorphic Sc​​ope 最新第一项
【发布时间】:2020-03-30 19:01:13
【问题描述】:

早安,

我在使用 Laravel 范围和 Eloquent 多态一对多关系获取最新项目时有点卡住了。

给定:

  • 我正在使用最新版本的 Laravel 6.x。
  • 我有两个模型:WebsiteStatus
  • Status 模型可重复使用,可与其他模型一起使用。
  • 每个网站都有多种状态。
  • 每次更改状态时,都会在 DB 中创建一条新记录。
  • 活动网站状态是数据库中的最新状态。

网站模型:

class Website extends Model
{
    public function statuses()
    {
        return $this->morphMany(Statuses::class, 'stateable');
    }

    public function scopePending($query)
    {
        return $query->whereHas('statuses', function ($query) {
            $query->getByStatusCode('pending');
        });
    }
}

状态模型:

class Statuses extends Model
{
    public function stateable()
    {
        return $this->morphTo();
    }

    public function scopeGetByStatusCode($query, $statusCode)
    {
        return $query->where('status_code', $statusCode)->latest()->limit(1);
    }
}

问题是当我打电话时:

Website::pending()->get();

pending() 范围将返回所有分配给它们的 pending 状态的网站,而不是当前具有活动 pending 状态(例如最新状态)的网站。

这是使用DB::getQueryLog() 返回的查询

select * from `websites` 
    where exists 
    (
        select * from `statuses` 
        where `websites`.`id` = `statuses`.`stateable_id` 
        and `statuses`.`stateable_type` = "App\\Models\\Website" 
        and `status_code` = 'pending' 
        order by `created_at` desc limit 1
    ) 
and `websites`.`deleted_at` is null

使用具有多态一对多关系的范围获取pending网站的正确方法是什么?

这里描述了类似的问题:https://laracasts.com/discuss/channels/eloquent/polymorphic-relations-and-scope

谢谢。

【问题讨论】:

  • 原始查询不太正确,它必须是 websites.id 而不是 website.id
  • 很好,但这只是一个错字,因为我在那里更改了一些措辞。 SQL 纯粹是一个示例输出。

标签: php laravel eloquent scopes has-many-polymorphs


【解决方案1】:

好的,经过一番研究,我偶然发现了这篇文章:https://nullthoughts.com/development/2019/10/08/dynamic-scope-on-latest-relationship-in-laravel/

解决方案非常雄辩(对不起,双关语不好):

protected function scopePending($query)
{
    return $query->whereHas('statuses', function ($query) {
        $query->where('id', function ($sub) {
            $sub->from('statuses')
                ->selectRaw('max(id)')
                ->whereColumn('statuses.stateable_id', 'websites.id');
         })->where('status_code', 'pending');
    });
}

【讨论】:

    猜你喜欢
    • 2020-12-20
    • 1970-01-01
    • 1970-01-01
    • 2017-03-31
    • 2015-05-29
    • 1970-01-01
    • 2020-04-19
    • 1970-01-01
    • 2017-09-21
    相关资源
    最近更新 更多