2013-04-22 97 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