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

时间:2019-12-18 19:57:01

标签: laravel laravel-5 eloquent eloquent--relationship laravel-6.2

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

除了这一部分之外,一切工作都很好,在浏览文档后,我还没有想过。

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

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

我这里缺少什么吗?这是我的数据库结构和模型关系:

目前的数据库结构:


用户:

id

名称


运行:

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);
    }

}

2 个答案:

答案 0 :(得分:1)

“运行”没有user_id列,我想这里是一个wherehas,因为您试图仅在某个用户有时间但并非所有运行都只包含该用户的时间的情况下获取运行

$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();

编辑:

“运行”与“用户”之间的关系实际上是与“时代”作为枢纽模型的多对多关系。 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');
    }
}

因此,您现在可以查询特定用户的所有运行,并且由于它使用时间作为数据透视表,因此您知道该用户将有时间进行返回的所有运行

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

所有参加跑步的用户

Run::find(1)->users();

答案 1 :(得分:0)

重新阅读您的要求:

  

用户拥有的时间(...)

您需要使用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的连接方式。如评论中所述,数据库结构当前不支持建议的逻辑。