如何从 hasManyThrough 雄辩关系返回 Laravel 中的单个模型
Posted
技术标签:
【中文标题】如何从 hasManyThrough 雄辩关系返回 Laravel 中的单个模型【英文标题】:How to return a single model in Laravel from a hasManyThrough eloquent relationship 【发布时间】:2018-09-25 10:23:46 【问题描述】:我的表结构如下:
tickets
- id
assignments
- id
- ticket_id
- staff_id
- role
- isAssigned
staff
- id
- username
我在tickets
模型上创建了一个hasManyThrough
关系,它通过assignments
表成功返回了与ticket
关联的所有staff
。
public function staff()
return $this->hasManyThrough(Staff::class, Assignment::class);
assignments
表可以为同一个role
的ticket
保存一条或多条记录,其中isAssigned
标志指定staff
关联是否处于活动状态。因此,对于给定的role
,只有 1 条记录将永远拥有isAssigned = 1
我利用query scopes
来限制hasManyThrough
关系返回的结果,例如:
public function scopeWithAssignedEngineer($builder)
$filter = function ($staff)
$staff->where([['isAssigned', 1], ['role', 'engineer']]);
;
return $builder->whereHas('staff', $filter)->with(['staff' => $filter]);
所以,如果我打电话给Ticket::withAssignedEngineer()->where('id', 123)->get();
,我会和指定的工程师一起得到我的票,但是,工程师是一个集合而不是一个项目。
ticket:
id: 123,
assigned_engineer: [
...
]
使用回复时,我可以致电 $ticket->assignedEngineer->first()
来联系工程师,但是,我宁愿不必在每个此类集合上都先致电。
所以;
问题 1
我的hasManyThrough
关系正确吗,还是我在这里把事情复杂化了?
问题 2
有什么我可以在我的scopes
上或在我的hasMany
关系上工作的东西,这些关系只会在collection
内返回一个item
,这样我就不必每次都调用->first()
?
【问题讨论】:
关系叫staff
还是assignedEngineer
?或者他们是不同的关系?
可以分配多个工程师吗?请在您的模型中分享您的员工定义。
hasManyThrough
无法仅返回 1 件商品。您可以使用->take(1)
,但它仍会被包装在一个集合中。您最好创建一个belongsToMany
以将tickets
连接到staff
,反之亦然。并使用assignments
作为数据透视表。
@JonasStaudenmeir - hasManyThrough
关系称为 staff
,它返回与 ticket
关联的所有 staff
。 scopeWithAssignedEngineer scope
使用 staff
关系,但对其进行进一步过滤。
响应中的assignedEngineer
只是staff
结果吗?还是按role
过滤?
【参考方案1】:
不是最优雅的解决方案,但它确实有效。
将assignedEngineer
更改为assignedEngineers
并将accessor 添加到Ticket
模型:
public function getAssignedEngineerAttribute()
return $this->assignedEngineers->first();
然后你可以像这样得到一个Staff
模型:
$ticket->assignedEngineer
如果您要返回 JSON 响应,请将其添加到 Ticket
:
protected $appends = ['assignedEngineer'];
【讨论】:
以上是关于如何从 hasManyThrough 雄辩关系返回 Laravel 中的单个模型的主要内容,如果未能解决你的问题,请参考以下文章
Laravel 雄辩用 whereHas 或其他限制 withCount