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();
注意:这假设您的关系是正确形成的,但不清楚 User
、Run
和 Time
是如何连接的。如评论中所述,数据库结构目前不支持建议的逻辑。
运行 没有 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();
我正在尝试列出用户有 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();
注意:这假设您的关系是正确形成的,但不清楚 User
、Run
和 Time
是如何连接的。如评论中所述,数据库结构目前不支持建议的逻辑。
运行 没有 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();