从 -many to many- 连接到 -one to many- 关系检索集合的最佳方法 (laravel7)
best way to retrive a collection from -many to many- connected to -one to many- relation (laravel7)
您可以在下图中看到我的数据库的一部分:
此设计的目标是让管理员能够将 alerts
发送到 users
,并通过 center
和 field
(动态)过滤。如果您认为这是一个糟糕的设计,请告诉我(请说出为什么以及我应该如何改进我的设计)。
现在,如果我想获得用户的提醒,我应该这样做:
$userAlerts = collect();
auth()->user()->branch()->first()->groups()->get()->each(function ($item, $key) use ($userAlerts) {
$item->alerts()->get()->each(function ($item, $key) use ($userAlerts) {
$userAlerts->push($item);
});
});
这段代码很荒谬,我不想这样做。
相反,我想做这样的事情:
$alerts = auth()->user()->branch()->groups()->alerts() // i want this // method 1
或
$alerts = auth()->user()->alerts() //or maybe this // method 2
我可以在不更改数据库的情况下做这样的事情吗? (方法 1 或 2)。
您可以在分支模型上使用 laravel 的默认 Has Many Through 来选择关联的警报
class Branch extends Model
{
public function alerts()
{
return $this->hasManyThrough(
'App\Models\Alert',
'App\Models\Group',
'branch_id', // Foreign key on alert table...
'group_id', // Foreign key on group table...
'id', // Local key on branch table...
'id' // Local key on group table...
);
}
}
使用这种方式,您可以将用户提醒查询为
$alerts = auth()->user()->branch()->alerts()
或者您可以使用第三方包 eloquent-has-many-deep,它可以轻松地在多个相关模型上扩展 hasManyThrough
class User extends Model
{
use \Staudenmeir\EloquentHasManyDeep\HasRelationships;
public function alerts()
{
return $this->hasManyDeep(
'App\Models\Alert',
['App\Models\Branch', 'App\Models\Group'], // Intermediate models, beginning at the far parent (User).
[
'user_id', // Foreign key on the "branch" table.
'branch_id', // Foreign key on the "group" table.
'group_id' // Foreign key on the "alert" table.
],
[
'id', // Local key on the "user" table.
'id', // Local key on the "branch" table.
'id' // Local key on the "group" table.
]
);
}
}
并且您可以直接获得用户提醒,如
$alerts = auth()->user()->alerts()
最后,您可以通过添加一些连接来直接拉取相关警报,从而在用户模型中定义警报关系
class User extends Model
{
public function alerts()
{
return $this->belongsTO('App\Branch', 'branch_id')
->join('branch_group', 'branches.id', '=', 'branch_group.branch_id')
->join('alerts', 'branch_group.group_id', '=', 'alerts.group_id')
->select('alerts.*');
}
}
您可以在下图中看到我的数据库的一部分:
此设计的目标是让管理员能够将 alerts
发送到 users
,并通过 center
和 field
(动态)过滤。如果您认为这是一个糟糕的设计,请告诉我(请说出为什么以及我应该如何改进我的设计)。
现在,如果我想获得用户的提醒,我应该这样做:
$userAlerts = collect();
auth()->user()->branch()->first()->groups()->get()->each(function ($item, $key) use ($userAlerts) {
$item->alerts()->get()->each(function ($item, $key) use ($userAlerts) {
$userAlerts->push($item);
});
});
这段代码很荒谬,我不想这样做。
相反,我想做这样的事情:
$alerts = auth()->user()->branch()->groups()->alerts() // i want this // method 1
或
$alerts = auth()->user()->alerts() //or maybe this // method 2
我可以在不更改数据库的情况下做这样的事情吗? (方法 1 或 2)。
您可以在分支模型上使用 laravel 的默认 Has Many Through 来选择关联的警报
class Branch extends Model
{
public function alerts()
{
return $this->hasManyThrough(
'App\Models\Alert',
'App\Models\Group',
'branch_id', // Foreign key on alert table...
'group_id', // Foreign key on group table...
'id', // Local key on branch table...
'id' // Local key on group table...
);
}
}
使用这种方式,您可以将用户提醒查询为
$alerts = auth()->user()->branch()->alerts()
或者您可以使用第三方包 eloquent-has-many-deep,它可以轻松地在多个相关模型上扩展 hasManyThrough
class User extends Model
{
use \Staudenmeir\EloquentHasManyDeep\HasRelationships;
public function alerts()
{
return $this->hasManyDeep(
'App\Models\Alert',
['App\Models\Branch', 'App\Models\Group'], // Intermediate models, beginning at the far parent (User).
[
'user_id', // Foreign key on the "branch" table.
'branch_id', // Foreign key on the "group" table.
'group_id' // Foreign key on the "alert" table.
],
[
'id', // Local key on the "user" table.
'id', // Local key on the "branch" table.
'id' // Local key on the "group" table.
]
);
}
}
并且您可以直接获得用户提醒,如
$alerts = auth()->user()->alerts()
最后,您可以通过添加一些连接来直接拉取相关警报,从而在用户模型中定义警报关系
class User extends Model
{
public function alerts()
{
return $this->belongsTO('App\Branch', 'branch_id')
->join('branch_group', 'branches.id', '=', 'branch_group.branch_id')
->join('alerts', 'branch_group.group_id', '=', 'alerts.group_id')
->select('alerts.*');
}
}