Ruby on rails Rails:使用CanCan根据单个模型的实例定义多个角色?
我目前一直在研究如何根据我们想要的每种情况来区分CanCan的角色。 在我们的应用程序中,有许多类别(如数学、英语、历史等),每个类别中都有许多课程 每个用户在每个类别上可以有许多不同的角色。例如,约翰可以成为数学的“读者”,这意味着他可以阅读所有的数学课程。John还可以成为英语的“作者”,这意味着他可以阅读所有英语课程,在英语类别中创建课程,并且只编辑/删除他在英语类别中创建的课程 如果这些是John仅有的角色,他将无法在导航栏中查看类别历史,并且将被拒绝访问历史中的课程 以下是建立关系的方式:Ruby on rails Rails:使用CanCan根据单个模型的实例定义多个角色?,ruby-on-rails,ruby,authorization,cancan,Ruby On Rails,Ruby,Authorization,Cancan,我目前一直在研究如何根据我们想要的每种情况来区分CanCan的角色。 在我们的应用程序中,有许多类别(如数学、英语、历史等),每个类别中都有许多课程 每个用户在每个类别上可以有许多不同的角色。例如,约翰可以成为数学的“读者”,这意味着他可以阅读所有的数学课程。John还可以成为英语的“作者”,这意味着他可以阅读所有英语课程,在英语类别中创建课程,并且只编辑/删除他在英语类别中创建的课程 如果这些是John仅有的角色,他将无法在导航栏中查看类别历史,并且将被拒绝访问历史中的课程 以下是建立关系的方
class User < ActiveRecord::Base
has_many :roles
def has_role?(role_sym)
roles.any? { |r| r.level.underscore.to_sym == role_sym }
end
end
class Category < ActiveRecord::Base
has_many :roles
has_many :courses
end
class Role < ActiveRecord::Base
belongs_to :user
belongs_to :category
attr_accessible :level, :category_id, :user_id
end
问题:
我已经试着解决这个问题3天了-请理解,我仍然是一个初学者!提前感谢在您的GEM文件中包括
class Ability
include CanCan::Ability
def initialize(user)
user||= User.new
can :read, :all
if user.role == 'admin'
can :manage, :all
else
can :read, :all
end
end
end
四,。要限制用户的资源,
在其控制器中使用以下过滤器
load_and_authorize_resource
五,。如果要限制视图中的某些内容不显示
<% if can? :manage, @flower %>
<td><%= link_to 'Edit', edit_flower_path(flower) %></td>
<% end %>
<% if can? :manage, @flower %>
<td><%= link_to 'Destroy', flower_path(flower), method: :delete, data: { confirm: 'Are you sure?' } %></td>
<% end %>
今天,我遇到了同样的需求,并找到了一种在计算机上实现这一点的方法 请按照以下简单步骤进行操作: 1) 使用您的角色名称在User类下创建一个常量:
class User < ActiveRecord::Base
ROLES = %w[admin moderator author banned]
end
2b)如果使用Mongoid,请在用户模型上添加以下字段:
field :roles_mask, type: Integer
3) 接下来,您需要将以下代码添加到用户模型中:
# in models/user.rb
def roles=(roles)
self.roles_mask = (roles & ROLES).map { |r| 2**ROLES.index(r) }.inject(0, :+)
end
def roles
ROLES.reject do |r|
((roles_mask.to_i || 0) & 2**ROLES.index(r)).zero?
end
end
4) 如果您使用的是没有强参数的Desive,请不要忘记将attr_accessible:角色添加到您的用户模型中。如果您正在使用带有强_参数的Desive,无论是作为Rails 3应用程序中的gem,还是Rails 4中内置的gem,请不要忘记将角色添加到控制器中的允许列表中:
class ApplicationController < ActionController::Base
before_filter :configure_permitted_parameters, if: :devise_controller?
protected
def configure_permitted_parameters
devise_parameter_sanitizer.for(:sign_up) {|u| u.permit(:email, :password, :password_confirmation, roles: [])}
end
end
就这样
我希望这能有所帮助
# in models/user.rb
def roles=(roles)
self.roles_mask = (roles & ROLES).map { |r| 2**ROLES.index(r) }.inject(0, :+)
end
def roles
ROLES.reject do |r|
((roles_mask.to_i || 0) & 2**ROLES.index(r)).zero?
end
end
class ApplicationController < ActionController::Base
before_filter :configure_permitted_parameters, if: :devise_controller?
protected
def configure_permitted_parameters
devise_parameter_sanitizer.for(:sign_up) {|u| u.permit(:email, :password, :password_confirmation, roles: [])}
end
end
<% for role in User::ROLES %>
<%= check_box_tag "user[roles][#{role}]", role, @user.roles.include?(role), {:name => "user[roles][]"}%>
<%= label_tag "user_roles_#{role}", role.humanize %><br />
<% end %>
<%= hidden_field_tag "user[roles][]", "" %>
# in models/user.rb
def is?(role)
roles.include?(role.to_s)
end
# in models/ability.rb
can :manage, :all if user.is? :admin