能力检测为什么不显示数据?(rails,cancancan)
Why doesn't the data is not displayed when going through the ability check?(rails,cancancan)
我想在我的 rails 应用程序中设置 3 个用户级别,如管理员、经理、客户。因此,我创建了一个作为用户的设计模型,并添加了一个迁移以在用户注册时将用户角色添加到 it.So,它存储用户角色(无论他是管理员、经理还是客户)。在我的应用程序中,有用于产品、交付和服务的模型和控制器。我想为每个模型设置访问级别。
所以管理员可以访问所有模型、控制器
经理有权访问产品、交付
客户可以访问服务
而我写的能力模型如下
class Ability
include CanCan::Ability
def initialize(user)
user ||= User.new # guest user (not logged in)
if user.roles == "admin"
can :manage , :all
elsif user.roles == "manager"
can :read, Products, Delivery
elsif user.roles == "customer"
can :read, Services
end
end
end
在我的产品展示视图中,我有以下代码
<% if can? :manage ,@products%>
<h1>Products</h1>
<% @products.each do |product| %>
<p> <%= product.name%>
<p> <%= product.price %><br>
<p> <%= product.qty %><br>
<%end%>
<%end%>
但即使我以管理员身份登录,我也看不到内容。但是当我删除能力检查行时,它可以在没有任何内容的情况下查看 issue.So 我预测问题应该在使用授权的方式。
而我的用户模型如下。
class User < ApplicationRecord
belongs_to :role
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
ROLES = %i[admin manager customer]
def user_params
params.require(:user).permit(:name, :email, :password, :password_confirmation, :role)
end
end
并在 views/devise/registrations/new.html.erb
我包含了以下代码块。
<div>
<%= f.collection_select(:role, User::ROLES, :to_s, lambda{|i| i.to_s.humanize}) %>
</div>
这就是我在products/show视图
中要检查的能力
<% if can? :manage ,@products%>
<h1>Products</h1>
<% @products.each do |product| %>
<p> <%= product.name%>
<p> <%= product.price %><br>
<p> <%= product.qty %><br>
<%end%>
<%end%>
user.roles
return 一个数组,您正在将数组与字符串 user.roles == "admin"
进行比较,字符串 user.roles == "admin"
将始终为 false
.
改为使用 User
模型中的方法 user.role?(:admin)
来检查角色
所以你的能力应该是这样的
class Ability
include CanCan::Ability
def initialize(user)
user ||= User.new # guest user (not logged in)
if user.role? :admin
can :manage, :all
elsif user.role? :manager
can :read, [Product, Delivery]
elsif user.role? :customer
can :read, Service
end
end
end
现在在你的控制器中你应该写一些谎言
class ProductsController < ActionController
load_and_authorize_resource
def index
...
end
# and other resouceful actions
end
load_and_authorize_resource
发挥了很多作用,其中之一是加载 current_user
(设计用户)有权访问的所有产品。
现在看来,您不必明确检查 <% if can? :manage ,@products%>
。 @products
将只有当前用户有权访问的产品。
<h1>Products</h1>
<%@products.present?%>
<% @products.each do |product| %>
<p><%= product.name %></p>
<p><%= product.price %></p>
<p><%= product.qty %></p>
<%end%>
<%else%>
<p>There are no products to display.</p>
<%end%>
我想在我的 rails 应用程序中设置 3 个用户级别,如管理员、经理、客户。因此,我创建了一个作为用户的设计模型,并添加了一个迁移以在用户注册时将用户角色添加到 it.So,它存储用户角色(无论他是管理员、经理还是客户)。在我的应用程序中,有用于产品、交付和服务的模型和控制器。我想为每个模型设置访问级别。
所以管理员可以访问所有模型、控制器
经理有权访问产品、交付
客户可以访问服务
而我写的能力模型如下
class Ability
include CanCan::Ability
def initialize(user)
user ||= User.new # guest user (not logged in)
if user.roles == "admin"
can :manage , :all
elsif user.roles == "manager"
can :read, Products, Delivery
elsif user.roles == "customer"
can :read, Services
end
end
end
在我的产品展示视图中,我有以下代码
<% if can? :manage ,@products%>
<h1>Products</h1>
<% @products.each do |product| %>
<p> <%= product.name%>
<p> <%= product.price %><br>
<p> <%= product.qty %><br>
<%end%>
<%end%>
但即使我以管理员身份登录,我也看不到内容。但是当我删除能力检查行时,它可以在没有任何内容的情况下查看 issue.So 我预测问题应该在使用授权的方式。 而我的用户模型如下。
class User < ApplicationRecord
belongs_to :role
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
ROLES = %i[admin manager customer]
def user_params
params.require(:user).permit(:name, :email, :password, :password_confirmation, :role)
end
end
并在 views/devise/registrations/new.html.erb 我包含了以下代码块。
<div>
<%= f.collection_select(:role, User::ROLES, :to_s, lambda{|i| i.to_s.humanize}) %>
</div>
这就是我在products/show视图
中要检查的能力<% if can? :manage ,@products%>
<h1>Products</h1>
<% @products.each do |product| %>
<p> <%= product.name%>
<p> <%= product.price %><br>
<p> <%= product.qty %><br>
<%end%>
<%end%>
user.roles
return 一个数组,您正在将数组与字符串 user.roles == "admin"
进行比较,字符串 user.roles == "admin"
将始终为 false
.
改为使用 User
模型中的方法 user.role?(:admin)
来检查角色
所以你的能力应该是这样的
class Ability
include CanCan::Ability
def initialize(user)
user ||= User.new # guest user (not logged in)
if user.role? :admin
can :manage, :all
elsif user.role? :manager
can :read, [Product, Delivery]
elsif user.role? :customer
can :read, Service
end
end
end
现在在你的控制器中你应该写一些谎言
class ProductsController < ActionController
load_and_authorize_resource
def index
...
end
# and other resouceful actions
end
load_and_authorize_resource
发挥了很多作用,其中之一是加载 current_user
(设计用户)有权访问的所有产品。
现在看来,您不必明确检查 <% if can? :manage ,@products%>
。 @products
将只有当前用户有权访问的产品。
<h1>Products</h1>
<%@products.present?%>
<% @products.each do |product| %>
<p><%= product.name %></p>
<p><%= product.price %></p>
<p><%= product.qty %></p>
<%end%>
<%else%>
<p>There are no products to display.</p>
<%end%>