【发布时间】:2019-05-08 16:43:30
【问题描述】:
我正在开发一个 Laravel 5.7 (API) 应用程序,它背后有一个 PostgreSQL 数据库。相关模型为:User(客户和员工)、Car 和 Request。
员工User 为Car 创建一个Request,该Car 属于客户 User。
关系是:
-
Car(作为客户):User=n:m -
Car:Request=1:n -
User:Request(作为员工)=1:n
(委婉地说,数据设计不是最理想的,但无论如何,这是目前的既定现实。)
现在到实际问题。我想显示一个客户 User的所有Requests:
Request::query()
->join('user_car', 'user_car.car_id', '=', 'request.car_id')
->join('user', 'user.id', '=', 'user_car.user_id')
->where('user.id', '=', $customer->id)
->select()
->get();
具有给定$customer->id 的客户 具有n Requests。并且上面调用的结果Collection 的长度是正确的。但是所有这些n 条目都是第一个条目的重复项。意思是:我得到了一个包含nRequest#1 实例的列表。
为什么第一次调用会返回对同一个 Model 对象的引用列表?这是一个(已知的)错误吗?
其他信息
关系:
class User extends \Illuminate\Foundation\Auth\User
{
// ...
public function cars()
{
return $this->belongsToMany('App\Car', 'user_car')->withTimestamps();
}
public function requests()
{
return $this->hasMany(Request::class, 'user_id');
}
}
class Car extends Model
{
// ...
public function users()
{
return $this->belongsToMany('App\User', 'user_car')->withTimestamps();
}
public function requests()
{
return $this->hasMany(Request::class);
}
}
class Request extends Model
{
// ...
public function car()
{
return $this->belongsTo(Car::class);
}
public function user()
{
return $this->belongsTo(User::class);
}
}
查询正确。
我记录了数据库请求,得到了生成的语句
SELECT *
FROM "request"
INNER JOIN "user_car" ON "user_car"."car_id" = "request"."car_id"
INNER JOIN "user" ON "user"."id" = "user_car"."user_id"
WHERE "user"."id" = 1;
...,并手动执行。结果表包含预期的n不同条目。
不仅仅是参考
结果Collection 的条目实例引用了不同的对象:
$test1 = $resultCollection->first();
$test2 = $resultCollection->last();
$test3 = spl_object_hash($test1);
$test4 = spl_object_hash($test2);
Xdebug 输出:
$test3 = "0000000077505ccd000000007964e0a8" <-- ccd0
$test4 = "0000000077505c33000000007964e0a8" <-- c330
解决方法
我找到了解决方法。这个电话
Request::whereIn('car_id', $customer->cars()->pluck('id')->toArray())->get();
...检索正确/预期的模型集。
【问题讨论】:
-
在您的查询中,您为什么不只是引用关系?你能展示你在你的用户、汽车和请求模型中的关系吗?此外,您不需要在查询中包含 ->select() 行,只需 get()。
-
@eResourcesInc 感谢您的评论。
1。 “引用关系”——你是什么意思?$customer->cars->... 然后呢?2“显示关系”刚刚更新了问题(参见附加信息)。3。 "->select() 行" -- 正确,谢谢! -
在您的解决方法中,为什么不直接设置 $requests = $customer->cars()->requests()?如果这给了你正确的结果,你为什么要把它写成一个完整的查询,而不是仅仅利用这些关系查询的简单性?
-
@eResourcesInc 1. "$customer->cars()->requests()" -- 这不起作用。
Customer#cars()返回一个BelongsToMany对象。所以我得到一个异常“调用未定义的方法...... BelongsToMany::requests()”。$customer->cars->requests()也不起作用,因为$customer->cars是Collection,它不知道request()方法。 2.“为什么...完整查询”——是的,我找到了一个可行的解决方案。但我想知道,为什么通过Builder的替代方式不起作用。要么我理解错了(然后我想知道,我的错误是什么),要么这是一个错误(然后我想报告它)。 -
当然它会返回一个关系,但我没有用 ->get() 写出整个查询,因为这取决于你。对汽车的调用会返回一组模型,然后您可以利用它们之间的关系。因此,对于汽车模型的请求关系,您绝对应该能够遵循两个级别的关系路径并获得所需的内容。我想我没有遵循帖子的要点,看到您正在尝试查看它是否是一个错误,但这可能是一些编码错误,因为这是基本功能,如果它有错误,那么几乎没有 laravel 应用程序可以正常工作。
标签: laravel laravel-5 laravel-5.7 data-retrieval