ruby-on-rails - 使用 cancancan 的 3 类角色的授权问题
问题描述
我有用户表(由设计创建),我添加了一个角色列,可以是:管理员、经理和代理。在 user.rb 我放了一个像这样的枚举:
class User < ApplicationRecord
enum role: { admin: 0, manager: 1, agent: 2 }
end
我正在使用 cancancan 并想做两件事:
1 - 如何根据注册用户的角色显示菜单或不同的按钮?在视图中,我是这样说的:
<% if current.present? && current_user.admin? %>
<%= link_to 'Purchases (Admin access)', admin_purchases_path, class: 'nav-link mr-5 ' %>
<% end %>
2 - 如何根据用户的角色显示特定页面?在我的 User.rb 我把这个:
def admin?
self.role == 'admin'
end
我在ability.rb上尝试它:
user ||= User.new # guest user (not logged in)
if admin?
can :manage, :all
else
can :read, :all
end
在控制器上,我放了:
load_and_authorize_resource
但我收到一个错误:
NoMethodError in Home#index
undefined method `admin?' for nil:NilClass
<% if current_user.admin? %> <<< On this line here
解决方案
您可以使用安全导航运算符来避免零错误:
<% if current_user&.admin? %>
然而,它仍然有点反模式。使用像 CanCanCan 这样的授权库的全部意义在于整合授权逻辑,而不是将其分散到您的控制器和视图中。
相反,您的视图应该询问 CanCanCan 用户是否有权执行链接所做的任何事情:
<% if can? :administrate, :purchases %>
<%= link_to 'Purchases (Admin access)', admin_purchases_path, class: 'nav-link mr-5 ' %>
<% end %>
它不必知道用户是否是管理员或管理员是否可以管理购买。那是CanCanCans的工作。
user ||= User.new # guest user (not logged in)
if user.admin?
can :manage, :all
can :administrate, :all
else
can :read, :all
end
在我的 User.rb 我把这个..
该代码是完全多余的。enum role: { admin: 0, manager: 1, agent: 2 }
已经创建了集成方法admin?
,manager?
并且agent?
。
您的问题ability.rb
是您在if admin?
没有实际指定收件人的情况下打电话。你应该打电话if user.admin?
。
推荐阅读
- xcode - 如何在 CarPlay 上显示歌曲
- timer - 可以同时执行两个 Linux 内核计时器处理程序吗?
- python - 过滤在 Pandas 中读取的 CSV 数据
- python - Scrapy:谁能告诉我为什么这段代码不能让我抓取后续页面?
- python - 将复杂 JSON 转换为 excel 或 CSV
- java - Android 8 之后有多少静态广播接收器无法工作?
- firebase - 颤动时无法从firestore获取文件
- c - Why cant I cast a void* back to an int* and dereference it?
- python - 在 Python 中使用带有 While 循环的生成器
- python - 使用带有 tensorflow lite 编译模型的 Grad-cam