AI回答,可以用。只要把 Article::class 通过 Gate 映射到你写的 UserPolicy ,在 ArticleController 里调用 $this->authorize('delete', $article) 或在 Blade 里用 @can('delete', $article) ,都会命中 UserPolicy::delete(User $user, Article $article) 。也就是,运行层面没有问题。
public function boot(): void
{
// Register policy mapping: Article model uses UserPolicy
Gate::policy(Article::class, UserPolicy::class);
}
class UserPolicy
{
/**
* Determine whether the user can delete the given Shuo.
*/
public function delete(User $user, Article $article): bool
{
return (int) $user->id === (int) $article->user_id;
}
}
两种做法的区别
- 命名/约定
- 使用 UserPolicy 授权 Article :需要显式注册映射(你已在 AppServiceProvider::boot 里 Gate::policy(Article::class, UserPolicy::class) )。类名与授权对象不一致,容易让后来者误解这个策略是用于 User 模型。
- 使用 ArticlePolicy :与模型一一对应、语义清晰。放在 App\Policies\ArticlePolicy 并按惯例命名时,Laravel能自动发现并绑定,无需手动 Gate::policy (默认目录和命名即可)。
- 可维护性
- ArticlePolicy 更直观:把 viewAny/create/update/delete 等操作都集中在与 Article 相关的策略类里,便于扩展和查看。
- UserPolicy 用来管 Article 不是不可行,但不符合多数团队和框架的惯例,后期阅读/协作成本更高。
- 控制器/视图使用
- 两者对控制器与视图的用法完全一致: $this->authorize('delete', $article) 与 @can('delete', $article) 都会通过 Gate 找到绑定到 Article::class 的策略类,不在乎类名,只在乎映射是否正确。
- 资源控制器的自动授权
- 如果你在控制器里使用 authorizeResource(Article::class, 'article') (放在构造函数),框架会按资源方法自动调用能力(如 destroy → delete )。这同样依赖模型→策略的绑定,用 ArticlePolicy 最自然;用 UserPolicy 也能工作,但更容易让人困惑。
建议
- 为了语义与团队惯例,建议将当前 UserPolicy 重命名为 ArticlePolicy 并放到 App\Policies\ArticlePolicy ;方法签名保持不变: delete(User $user, Article $article): bool 。
- 之后可以去掉手动 Gate::policy ,让框架自动发现;或者保留明确的 Gate::policy(Article::class, ArticlePolicy::class) 显式映射也可。
- 视图里的 @can('delete', $article) 和控制器里的 authorize('delete', $article) 不需要改动。

被折叠的 条评论
为什么被折叠?



