在我的rails应用程序中(我使用设计和cancan),每个(注册)用户属于完全一个角色('管理员'或'用户')但至少 一组(类似'家庭','朋友','同事')。在运行时,当创建新文件夹(见下文)时,可以设置与一个或多个组的habtm关系,该关系定义谁可以访问该文件夹。完全选择 no 组应该会生成一个全球可访问的文件夹(即用户无需登录即可访问这些文件夹)。但是现在,我还不知道如何在我的ability.rb中定义这样的全球可访问文件夹,因为我不知道如何定义“可以读取没有与之关联的组的文件夹”。
我的app/models/ability.rb
的相关片段如下所示:
user ||= User.new
if user.role? :Administrator
can :manage, :all
elsif user.role? :Users
# user should only be able to read folders, whose associated groups they are member of
can :read, Folder, :groups => { :id => user.group_ids }
else
# here goes the world-wide-accessible-folders part, I guess
# but I don't know how to define it:
## can :read, Folder, :groups => { 0 } ???
end
我的app/controllers/folders_controller.rb
的相关片段如下所示:
class FoldersController < ApplicationController
before_filter :authenticate_user!
load_and_authorize_resource
有人能给我一个暗示吗?
答案 0 :(得分:4)
前几天我遇到了同样的问题。我在阅读了CanCan自述文件后想出了解决方案,如果你还没有,你应该这样做。
您可以在此处查看我的解决方案:Context aware authorization using CanCan
为了给出更具体针对您的用例的答案,请执行以下操作:
在你的应用程序控制器中,你需要定义一些能够挑选你能力的逻辑。
class ApplicationController < ActionController::Base
check_authorization
def current_ability
if <no group selected logic> # Maybe: params[:controller] == 'groups'
@current_ability = NoGroupSelectedAbility.new(current_user)
else
@current_ability = GroupSelectedAbility.new(current_user)
end
end
# Application Controller Logic Below
end
然后,您需要在app / models /文件夹中创建一项新能力(或多种能力)。你也可以做这样的酷事:
if request.path_parameters[:controller] == groups
@current_ability = GroupsAbility.new(current_group_relation)
end
其中current_group_relation在app / controllers / groups_controller.rb中定义。这将为您提供特定控制器的特定功能。请记住,父类可以在Ruby中调用子类中的方法。您可以在控制器中定义一个方法,并从ApplicationController中调用它,只要您确定当前正在使用哪个控制器来处理请求。
希望有所帮助。
编辑:我想向您展示自定义功能的样子。# File path: app/models/group_ability.rb
class GroupsAbility
include CanCan::Ability
# This can take in whatever you want, you decide what to argument to
# use in your Application Controller
def initialize(group_relation)
group_relation ||= GroupRelation.new
if group_relation.id.nil?
# User does not have a relation to a group
can :read, all
elsif group_relation.moderator?
# Allow a mod to manage all group relations associated with the mod's group.
can :manage, :all, :id => group_relation.group.id
end
end
end