Laravel返回具有第一个模型副本的收藏集

时间:2018-12-06 22:29:12

标签: laravel laravel-5 laravel-5.7 data-retrieval

我正在开发带有PostgreSQL数据库的Laravel 5.7(API)应用程序。相关模型为:User(客户和员工),CarRequest

雇员 User为{<1> customer Request的{​​{1}}创建Car

这些关系是:

  • User (作为客户 Car : User =
  • n:m Car : Request =
  • 1:n User : (作为雇员) Request =

enter image description here

(数据设计是次优的,总之,但无论如何,这是目前的现实。)

现在是实际问题。我要显示客户的所有1:n Request

User

具有给定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个。上面调用的结果Request的长度是正确的。但是所有这些Collection条目都是第一个条目的重复。意思是:我得到一个包含n的{​​{1}}个实例的列表。

为什么第一次调用会返回对同一n对象的引用列表?是(已知的)错误吗?


其他信息

关系:

Request#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; 的entry实例引用了不同的对象:

n

Xdebug输出:

Collection

解决方法

我找到了解决方法。这个电话

$test1 = $resultCollection->first();
$test2 = $resultCollection->last();
$test3 = spl_object_hash($test1);
$test4 = spl_object_hash($test2);

...检索正确/期望的模型集。

1 个答案:

答案 0 :(得分:1)

首先,请注意,您的对象散列实际上并不相同,并且您可能要处理两个单独的实例。

您可能遇到的问题是列名不明确。当您JOIN一起使用多个表时,任何匹配/重复的列名称都将包含最后一个匹配列的值。您的SQL GUI /客户端通常将它们分开。不幸的是Laravel没有前缀机制,只是使用了一个关联数组。

假设所有表的主键列为id,那么结果集中的每个Request对象都将具有相同的ID-您在WHERE中传递的用户ID条件。

您可以通过显式选择需要防止歧义的列来解决现有查询中的问题。使用->select(['request.*'])将返回的信息限制为Request对象数据。