如何使用 Laravel 的 Eloquent 关系与 Eager Loading 连接 3 个表?
Posted
技术标签:
【中文标题】如何使用 Laravel 的 Eloquent 关系与 Eager Loading 连接 3 个表?【英文标题】:How to join 3 tables with Laravel's Eloquent relationships with Eager Loading? 【发布时间】:2019-07-09 03:04:06 【问题描述】:所以,order
有一个 foreign_key offer_id
。
而offer
有一个foreign_key item_id
。
一件商品可能有多个报价。但是每个报价都有一个项目。
一个报价可能有多个订单。但是每个订单都有一个报价。
当我这样做时:
$orders = Auth::user()->orders()
->with('offer')
->get();
我明白了:
id: 3,
user_id: 1,
offer_id: 5,
created_at: "2019-02-15 00:40:31",
updated_at: "2019-02-15 00:40:31",
offer:
id: 5,
item_id: 3,
created_at: "2019-02-15 00:39:40",
updated_at: "2019-02-15 00:39:40"
如您所见,我可以通过item_id: 3
获得此优惠
但我想得到整个项目;它的所有列,而不仅仅是 id。
通常,您会加入这两个表。 如何用 Eloquent 做到这一点?
这是我雄辩的人际关系:
订购
public function offer()
return $this->belongsTo(Offer::class);
优惠
public function orders()
return $this->hasMany(Order::class);
public function item()
return $this->hasOne(Item::class);
物品
public function offers()
return $this->belongsToMany(Offer::class);
【问题讨论】:
【参考方案1】:@MihirBhende 和@swonder 的答案指出了正确的方向。
确实应该是:
$orders = Auth::user()->orders()
->with('venue')
->with('offer.item')
->get();
或(同样的事情):
$orders = Auth::user()->orders()
->with(['venue', 'offer.food'])
->get();
但Offer
和Item
模型的关系应该颠倒:
优惠
public function item()
return $this->belongsTo(Item::class);
物品
public function offers()
return $this->hasMany(Offer::class);
【讨论】:
【参考方案2】:如果你所说的食物是指订单中的物品,那么:
$orders = Auth::user()->orders()
->with('offer', 'offer.orders', 'offer.item')
->get();
【讨论】:
我收到了RelationNotFoundException Call to undefined relationship [items] on model [App\Order].
你的项目中的items关系在哪里,是订单模型吗?
请查看更新后的描述。我添加了关系。
仍然无法正常工作:SQLSTATE[42S22]:找不到列:1054 'where 子句'中的未知列 'items.offer_id'(SQL:select * from items` where items.offer_id in (2, 4, 5))` 就我所见,它试图在 items 中寻找一个不存在的 offer_id。应该反过来。那么也许关系是错误的?
您在报价模型中指定了一个关系,即预期 item_id 列。表结构是什么样的?【参考方案3】:
Laravel Eager Loading
在下面你会发现嵌套的急切加载:
要急切加载嵌套关系,您可以使用“点”语法。例如,让我们在一个 Eloquent 语句中急切地加载本书的所有作者和作者的所有个人联系人:
$books = App\Book::with('author.contacts')->get();
在您的情况下,我们可以使用关系之间的点表示法获得嵌套的。
$orders = Auth::user()->orders()
->with(['offer', 'offer.item'])
->get();
【讨论】:
你的意思是offer.items
不是offer.orders
,对吗?它仍然无法正常工作 - RelationNotFoundException Call to undefined relationship [items] on model [App\Offer].
你说offer有订单,order有商品。所以它会是offer.orders.items
来获取物品。在您的订单模型上,您必须定义与 Item 模型的关系。这似乎是$this->hasMany()
。如果订单可以有很多项目。
没有。订单有报价,报价有商品。看看我在描述的前两行中给出的外键,同时我更新它以包含我在代码中的关系。
对不起,我读错了,所以应该是order.offers.items
。我已经更新了上面的答案,应该可以正常工作。只要您的 Offer 模型与商品有关系。
@padawanTony 这不是物品,它只是物品,因为您的关系是 HasOne。所以请看我更新的答案。以上是关于如何使用 Laravel 的 Eloquent 关系与 Eager Loading 连接 3 个表?的主要内容,如果未能解决你的问题,请参考以下文章
Laravel 5:如何使用 'where' 或 'orderBy' 使用 eloquent?
如何使用 eloquent 在 laravel 中编写多个连接
Laravel Eloquent - orWhereHas 方法 - 何时使用以及如何使用