Laravel pivot table 关系的优化

Optimization of Laravel pivot table relationship

我有一个名为 invite_riskarea 的支点 table,其设计如下:

此 table 处理具有特定用户(通过邀请 ID)访问特定风险字段的权限。每个风险字段都与一个风险区域相关联,该风险区域充当特定风险字段的主要容器。

在模型中 Invite 我有这样的关系:

public function riskareas()
{
    return $this->belongsToMany(Riskarea::class)->withPivot('riskfield_id', 'insert', 'edit', 'view');
}

通过这种方式,我可以 return 与特定邀请关联的所有风险区域,并且我应该能够 return 与同一邀请模型中的特定风险区域关联的所有风险区域。

正如您从 table invite_riskarea 中看到的,我有三个列,分别称为 inserteditdelete。这些列管理分配给特定用户(通过邀请 ID)的权限类型,用于属于风险区域的特定风险字段。

我正在尝试通过以下方式检索 riskarea 权限:

$invite = Invite::where('id', 58)->first();
$riskarea = $invite->riskareas[0];
$riskfield = $riskareas->riskfields[0];
echo 'view permission => ' . $riskfield->insert;

问题是我无法在 Invite 模型中设置正确的关系,return 只为 riskfield 关联的权限列的数据透视表riskarea.

所以我设法以这种方式处理这种情况:

$riskareas = Riskarea::all();

foreach ($riskareas as &$riskarea) {
    foreach ($riskarea->riskfields as &$riskfield) {
        $result = DB::table('invite_riskarea')
            ->select('insert', 'edit', 'view')
            ->where([
                'riskarea_id' => $riskarea->id,
                'riskfield_id' => $riskfield->id
            ])
            ->first();

        if ($result) {
            $riskfield->insert = $result->insert;
            $riskfield->edit = $result->edit;
            $riskfield->view = $result->view;
        }
    }
}

基本上,我得到了所有的风险区域,然后我遍历了相关的风险区域。对于每个风险字段,我都获得了 invite_riskarea table 中的权限,然后我得到了我想要的正确结构。

总结一下:

  1. 是否真的可以创建模型关系,return是 riskfield 而不是 riskarea 的权限?
  2. 我的 table 实施是否足以应对这种情况?
  1. 我建议您重新定义 Riskfield 模型与 Invite 模型的 many-to-many 关系。

    您还可以在 Invite 模型中定义与 riskfield 的直接 many-to-many 关系。这对您个人来说是多么方便。

    所以相反的many-to-many关系

    public function invites()
    {
        return $this->belongsToMany(Invite::class)->withPivot('insert', 'edit', 'view');
    }
    

    然后获取与指定邀请关联的所有对象的 Riskfields:

     $riskfields = Riskfields::wherehas('invites' . function (Builder $query) use ($invite_id) {
         $query->where('invites.id', $invite_id);
     })->with('invites')->get();
    

    然后就可以通过指定的方式访问数据透视表table中需要的字段了:

     foreach ($riskfields as $riskfield) {
         foreach ($riskfield->invites as $invite) {
             $insertRiskField = $invite->pivot->insert;
             $editRiskField = $invite->pivot->edit;
             $viewRiskField = $invite->pivot->view;
         }
     }
    

    预加载对数据库执行一个查询

  2. Documentation Laravel