过滤具有某些特定状态的事件

Filter Events which has some specific status

我正在尝试查询我的数据库以仅获取具有 'CONFIRMED' 状态的行,但状态保存在日志 table 中,而不是我需要执行的事件中查询。 logs table 存储所有手术状态,ID 为 1 的手术的当前状态是插入的最后一行 surgery_id 1. 我如何获得手术具有的所有事件状态 CONFIRMED?

这是我的数据库结构:

 Surgery           Events              Log
    id               id                id
patient_id       surgery_id         surgery_id
                                    status_id

我正在使用 laravel v5.7.28,带有 postgresql 数据库。

surgery 型号:

public function status()
{
    return $this->hasMany(Cirurgia_log::class)
        ->orderBy('created_at', 'desc');
}

如果我使用下面的代码,而不是第一个,我可以成功获得最后一个状态:

public function status()
{
    return $this->hasMany(Log::class)
        ->orderBy('created_at', 'desc')->first();
}

但是,对于这个,我无法使用 whereHas 功能。

surgery 关系在 Events 模型上定义:

public function surgery()
{
    return $this->belongsTo(Surgery::class, 'surgery_id');
}

我尝试使用下面的代码,但是,对于这个代码,如果手术被确认但现在被取消,一旦手术已经在某个时候被确认,与该手术对应的事件也将被返回。

Events::whereHas('surgery.status', function ($query){
    $query->where('status_id', env('CONFIRMED'));
})->get();

总而言之,我只需要获取与该事件相关的手术具有 CONFIRMED 状态的事件。

您可以简单地将 HasMany 换成 HasOne:

public function status()
{
    return $this->hasOne(Log::class)
        ->orderBy('created_at', 'desc');
}

status 作为一个词的问题是它有歧义。单数和复数是一样的,这让人很难确定我们是在谈论一个还是多个。所以我可能会选择 latestStatus()HasOne 以及 status()HasMany 来涵盖两者。

public function status()
{
    return $this->hasMany(Log::class)
        ->orderBy('created_at', 'desc');
}

public function latestStatus()
{
    return $this->hasOne(Log::class)
        ->orderBy('created_at', 'desc');
}

我用下面的代码解决了:

public function scopeConfirmedMaterials()
{
    return $this->whereHas('surgery.latestStatus', function ($query){
        $query->where('status_id', env('CONFIRMED'));
    })->get()
        ->filter(function ($event){
            return $event->surgery
                ->latestStatus
                ->status_id == env('CONFIRMED');
        });
}

事件模型上的surgery关系:

public function surgery()
{
    return $this->belongsTo(Surgery::class);
}

latestStatus关系,在Surgery模型上:

public function latestStatus()
{
    return $this->hasOne(Log::class)
        ->orderBy('created_at', 'desc');
}

EventController:

public function getEvent(){
    return response()->json(
        'data' => Events::confirmedMaterials();
    );
}