Laravel - 根据子关联获取父数据

Laravel - Getting parent data depending on child association

我正在尝试列出用户有 TIME 的所有 运行s(将 运行s 视为比赛)。用户不会总是运行,所以不会总是有时间。

除这一部分外,一切都很好,我在查看文档后还没有弄明白。

目前我正在尝试以下但它不会产生任何用户,只是一个空数组:

$runs = Run::with('times')->where('user_id', $user->id)->get();

我在这里遗漏了什么吗?这是我的数据库结构和模型关系:

目前数据库结构:


用户:

id

姓名


运行S:

id

姓名


次:

id

时间

user_id

run_id


模特们:

用户:

public function times()
{
    return $this->hasMany(Time::class);
}

运行:

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Run extends Model
{    
    public function user()
    {
        return $this->belongsTo(User::class);
    }

    public function times()
    {
        return $this->hasMany(Time::class);
    }
}

时间:

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Time extends Model
{
    public function user()
    {
        return $this->belongsTo(User::class);
    }

    public function run()
    {
        return $this->belongsTo(Run::class);
    }

}

重新阅读您的要求:

"where a user has a TIME ( ... )"

您需要使用 has('times') 加载存在关系的 Run 记录。 with() 不约束查询,它只急切加载关系:

$runs = Run::has('times')->with('times')->where('user_id', $user->id)->get();

注意:您可以在单个查询中同时使用 has()with() 来约束父模型并预先加载关系以便以后使用。

编辑:->where('user_id', $user->id); 可能有问题,但如果您已经有 $user,您可以直接查询:

$runs = $user->runs()->has('times')->with('times')->get();

注意:这假设您的关系是正确形成的,但不清楚 UserRunTime 是如何连接的。如评论中所述,数据库结构目前不支持建议的逻辑。

运行 没有 user_id 列,我相信 whereHas 是您想要的,因为您试图只在某个用户拥有的地方获得 运行s不是所有 运行 的时间,只有该用户的时间

$runs = Run::whereHas('times', function ($builder) use ($user) { 
        $query->where('user_id', $user->id);
    })->get();

此外,如果您想为该用户预加载时间并且仅该用户可以添加约束条件

$runs = Run::whereHas('times', function ($builder) use ($user) { 
        $query->where('user_id', $user->id);
    })->with(['times' => function ($query) use ($user) {
        $query->where('user_id', $user->id);
    }])->get();

编辑:

运行s 和 Users 之间的关系实际上是多对多关系,其中 Times 充当枢轴模型。 Laravel 支持这种排列方式,让我们来设置一下吧。

use Illuminate\Database\Eloquent\Relations\Pivot;

class Time extends Pivot
{
     public function run()
     {
         return $this->belongsTo('\App\Run');
     }

    public function user()
    {
         return $this->belongsTo('\App\User');
    }
}
class User extends Model
{
    public function times()
    {
        return $this->hasMany('\App\Time');
    }

    public function runs()
    {
        return $this->belongsToMany('\App\Run')->using('\App\Time');
    }
}
class Run extends Model
{
    public function times()
    {
        return $this->hasMany('\App\Time');
    }

    public function users()
    {
        return $this->belongsToMany('\App\User')->using('\App\Time');
    }
}

所以现在您可以查询特定用户的所有 运行,因为它使用时间作为枢轴 table,您知道用户将有一个时间用于所有 运行就这样了returns

User::find(1)->runs();

所有参与 运行

的用户
Run::find(1)->users();