laravel - 在 Laravel 中过滤权限时的最佳性能方法
问题描述
我正在开发一个应用程序,用户可以通过许多不同的场景访问许多表单。在向用户返回表单索引时,我正在尝试构建具有最佳性能的方法。
用户可以通过以下场景访问表单:
- 拥有表格
- 团队拥有表格
- 对拥有表单的组具有权限
- 拥有拥有表单的团队的权限
- 拥有表单权限
如您所见,用户可以通过 5 种可能的方式访问表单。我的问题是如何最有效地将一组可访问表单返回给用户。
表格政策:
我试图从模型中获取所有表单,然后通过表单策略过滤表单。这似乎是一个性能问题,因为在每次过滤器迭代中,表单都会通过 contains() 雄辩的方法 5 次,如下所示。数据库中的表单越多意味着这变得越慢。
FormController@index
public function index(Request $request)
{
$forms = Form::all()
->filter(function($form) use ($request) {
return $request->user()->can('view',$form);
});
}
FormPolicy@view
public function view(User $user, Form $form)
{
return $user->forms->contains($form) ||
$user->team->forms->contains($form) ||
$user->permissible->groups->forms($contains);
}
尽管上述方法有效,但它是一个性能瓶颈。
从我可以看到我的以下选项是:
- FormPolicy 过滤器(当前方法)
- 查询所有权限(5)并合并为单个集合
- 查询所有权限的所有标识符 (5),然后使用IN()语句中的标识符查询 Form 模型
我的问题:
哪种方法可以提供最佳性能,是否有任何其他选项可以提供更好的性能?
解决方案
我希望做一个 SQL 查询,因为它的性能会比 php 好得多
像这样的东西:
User::where('id', $request->user()->id)
->join('group_users', 'user.id', 'group_users.user_id')
->join('team_users', 'user.id', 'team_users.user_id',)
->join('form_owners as user_form_owners', function ($join) {
$join->on('users.id', 'form_owners.owner_id')
->where('form_owners.owner_type', User::class);
})
->join('form_owners as group_form_owners', function ($join) {
$join->on('group_users.group_id', 'form_owners.owner_id')
->where('form_owners.owner_type', Group::class);
})
->join('form_owners as team_form_owners', function ($join) {
$join->on('team_users.team_id', 'form_owners.owner_id')
->where('form_owners.owner_type', Team::class);
})
->join('forms', function($join) {
$join->on('forms.id', 'user_form_owners.form_id')
->orOn('forms.id', 'group_form_owners.form_id')
->orOn('forms.id', 'team_form_owners.form_id');
})
->selectRaw('forms.*')
->get();
从我的脑海中,未经测试,这应该为您提供用户、他的组和这个团队拥有的所有表单。
但是,它不会查看用户在组和团队中查看表单的权限。
我不确定您是如何为此设置身份验证的,因此您需要为此修改查询以及数据库结构中的任何差异。
推荐阅读
- javascript - 获取深度嵌套的属性值
- javascript - 如何更改 JavaScript 博客小部件中的帖子标题位置
- c# - 获取 AD 用户属性下属性编辑器中的所有属性
- angular - 部署在 github 页面上的应用程序将资产的 GET 发送到错误的地址
- spring - Spring :: Hikari Pool-1 starting... 在运行应用程序时卡在这条线上
- django - 使用管理应用程序验证 django 多表继承
- javascript - 获取多选下拉列表的 selectedIndex
- c++ - 插入排序算法在放入函数时表现不同
- javascript - 如何使用 React 和 JavaScript 将 .txt 文件转换为 JSON
- amazon-web-services - AWS 上的 ElasticSearch:需要文件的令牌过滤器