Laravel 11中Blade文件如何正确调用Work模型的delete权限验证?
问题描述
我正在使用Laravel 11,在Blade文件中使用了如下指令:
@can('delete', $work) @endcan
我的WorkPolicy文件中有如下函数:
public function delete(User $user, Work $work): bool { Log::info('I delete a work'); }
问题在于Blade文件中的$work变量并非Work模型类型,导致Policy里的delete方法从未被调用。我希望能在调用@can指令前对$work变量进行转换,但不想像下面这样额外发起一次数据库请求:
@php $workPolicy = App\Models\Work::find($work->id) @endphp @can('delete', $workPolicy)
解决方案
以下是几种无需额外数据库请求的处理方式:
1. 创建无查询的模型实例
可以直接用现有数据创建一个Work模型的空实例,Laravel授权系统会识别模型类型,不会触发数据库查询:
@can('delete', new App\Models\Work(['id' => $work->id]))
或者拆分写法更清晰:
@php $workModel = new App\Models\Work(); $workModel->id = $work->id; // 若授权逻辑需要其他字段,也可以一并赋值,比如$workModel->user_id = $work->user_id; @endphp @can('delete', $workModel)
2. 直接指定策略类
跳过模型类型匹配,在@can中直接指定对应策略类,同时传入当前的$work数据:
@can('delete', [App\Policies\WorkPolicy::class, $work])
然后调整WorkPolicy的delete方法参数类型,适配传入的非模型数据:
public function delete(User $user, $work): bool { Log::info('I delete a work'); // 根据实际$work的结构编写授权逻辑,比如判断用户是否拥有该资源权限 return $user->id === $work->user_id; }
3. 控制器层提前转换
如果视图对应的控制器中可以提前将$work转换为Work模型实例,再传递到视图,就能直接在Blade中使用@can:
// 控制器代码 $work = App\Models\Work::find($work->id); // 此处转换为模型实例 return view('your-view', compact('work'));
视图中直接调用:
@can('delete', $work) @endcan
内容的提问来源于stack exchange,提问作者Dom
相关产品推荐
相关产品推荐

