2013-04-22 54 views
0

如何正确授权与devise和cancan嵌套的资源?我已经从文档中实施了建议的程序,但没有成功。与devise和cancan的嵌套资源授权

此问题涉及能力模型不能从使用设计和cancan gems的嵌套资源的层获取用户标识。但是,我可以从中间层获取用户标识。任何帮助是极大的赞赏!

我有一个嵌套的资源,像这样:

resources :users do 
    resources :clients do 
     resources :positions 
    end 
    end 

    resources :clients do 
    resources :positions 
    end 

    resources :users do 
    resources :positions 
    end 

    resources :users 
    resources :clients 
    resources :positions 

使用以下的position模式控制器:

class PositionsController < ApplicationController 
    before_filter :grab_client_from_client_id 
    load_and_authorize_resource :user 
    load_and_authorize_resource :client, through: :user, shallow: true 
    load_and_authorize_resource :position, through: :client, except: [:index], shallow: true 
    ... 
end 

的ability.rb文件:

class Ability 
    include CanCan::Ability 

    def initialize(user) 

    user ||= User.new # guest user (not logged in) 

    if user.has_role? :admin 
     can :manage, :all 
    elsif user.has_role? :management 
     can [:create, :read, :update], :all 
    else 
     can :read, :all, user_id: user.id 
    end 

    end 
end 

此结果在非管理员/非管理员用户收到以下错误:

undefined method 'user_id' for #<User:0x5227d40>

显然有些东西设置不正确。我已经翻阅了每篇宝石的文档,并在各处寻找解决方案。

我还会在下面提供我的模型关系。


class User < ActiveRecord::Base 
    has_many :clients 
    has_many :positions, through: :clients 
    resourcify 
    ... 
end 


class Client < ActiveRecord::Base 
    resourcify 
    has_many :checklogs 
    has_many :positions 
    belongs_to :user 
end 


class Position < ActiveRecord::Base 
    resourcify 
    belongs_to :client 
    delegate :user, to: :client, allow_nil: true 
end 

回答

4

问题就出在这行:

can :read, :all, user_id: user.id 

当你正在检查用户是否可以读的东西它会检查你想读什么。

既然你有这条线在您的控制器:

load_and_authorize_resource :user 

您尝试授权的资源是用户。

您的能力将比较user.user_idcurrent_user.id。用户没有user_id,所以这是错误来自的地方。

根据您的代码,我怀疑您希望用户只能读取他的东西,除非他是经理或管理员。

您可以通过以下方式实现这一目标:

if user.has_role? :admin 
    can :manage, :all 
elsif user.has_role? :management 
    can [:create, :read, :update], :all 
else 
    can :read, User, id: user.id 
    can :read, Client, user_id: client.id 
    can :read, Position, client: { user_id: user.id } 
end 

这样,用户只能访问,他有一个关系到这些模型。

+0

谢谢!这是我正在寻找的。 – Tomanow 2013-04-23 18:31:25