在使用三向数据透视表时,我正努力在Laravel中进行急切的加载。数据库设置如下:
+-------+--------+-------+-------------+
| deals | venues | users | redeems |
+-------+--------+-------+-------------+
| id | id | id | deal_id |
| title | name | name | user_id |
| | | | venue_id |
| | | | redeemed_at |
+-------+--------+-------+-------------+
redeems
显然是数据透视表。用户模型如下所示:
<?php
class User extends Authenticatable
{
/**
* The deals redeemed by the user.
*/
public function deals()
{
return $this->belongsToMany(Deal::class, 'redeems')
->withPivot(['venue_id', 'redeemed_at']);
}
}
这允许我这样做:
$users = Users::with('deals')->all();
然后我会很好地了解用户以及他们在这样的结构中兑换的所有交易:
{
"id": 1,
"name": "Diederik",
"deals": [
{
"id": 33,
"title": "Deal Title",
"pivot": {
"user_id": 1,
"deal_id": 33,
"venue_id": 50
}
}
]
}
现在我想通过急切加载来添加场地信息,而不是之后查询$user->pivot->venue_id
。
我尝试在belongsTo
模型中设置deal
关系,然后像这样嵌套:$users = Users::with('deals.venue')->all();
但这不起作用,因为交易表没有外国人一个场地的关键。这是因为交易可以应用于多个场所。
我知道使用普通的数据库查询很容易实现这一点,但是对于我们的API工作方式,必须使用雄辩的with
关系函数,因为我们的URL设置包含这种方式
TLDR:如何急切加载嵌套的三向数据透视表关系。
答案 0 :(得分:1)
我很想你把数据透视表视为另一个模型(Redeem)。然后与其他表格/模型(交易/场地/用户)建立一对多的关系,这样您就可以使用Eloquent这样的查询来延迟加载您需要的对象:
$redeems = User::find($id)->redeems;
$redeems->load(['venue','deal']);
return $redeems;
要以精确的方式格式化数据/响应,如果使用5.5,则可以使用API Resources。或Fractal为5.4或以下。
答案 1 :(得分:0)
如果我正确理解您的问题,那么您希望获得特定场所的交易和场所之间存在一对多的关系。通常,你会在交易模型中创建一个hasMany()或belongsToMany()关系,然后如果你想进一步过滤场地,你会写一个像这样的Eloquent子查询:
// Gets first venue of deals
Users::with('deals', 'deals.venues' => function ($query) {
$query->first();
})->all();