我有一个嵌套资源,我正在使用Cancan进行授权。我需要能够访问父对象,以便能够授权子进程的:index
操作(因为没有为:index
操作传递子实例)。
# memberships_controller.rb
class MembershipsController < ApplicationController
...
load_and_authorize_resource :org
load_and_authorize_resource :membership, through: :org
..
end
ability.rb
can [:read, :write], Membership do |membership|
membership.org.has_member? user
end
不幸的是,索引操作没有与之关联的任何成员资格实例,因此您无法恢复以检查权限。
为了检查权限,我需要询问父对象(组织)并询问当前用户是否是成员,例如。
# ability.rb
...
can :index, Membership, org: { self.has_member? user }
Cancan声明您可以使用以下机制访问父级的属性: https://github.com/ryanb/cancan/wiki/Nested-Resources#wiki-accessing-parent-in-ability
# in Ability
can :manage, Task, :project => { :user_id => user.id }
然而,这只是通过比较对我的情况不起作用的属性。
有没有办法在权限内访问父对象本身?
答案 0 :(得分:4)
我最近遇到了同样的问题并最终得到以下结果(假设您有Org
型号):
class MembershipsController < ApplicationController
before_action :set_org, only: [:index, :new, :create] # if shallow nesting is enabled (see link at the bottom)
before_action :authorize_org, only: :index
load_and_authorize_resource except: :index
# GET orgs/1/memberships
def index
@memberships = @org.memberships
end
# ...
private
def set_org
@org = Org.find(params[:org_id])
end
def authorize_org
authorize! :access_memberships, @org
end
end
ability.rb:
can :access_memberships, Org do |org|
org.has_member? user
end
答案 1 :(得分:1)
你不能做这样的事吗?
class Ability
include CanCan::Ability
def initialize(user)
user ||= User.new # guest user (not logged in)
can :index, Membership, org: {id: user.memberships.map(&:org_id)}
end
end