1

私は最近、承認のために cancan (1.6.9) を Rails (3.2.10) プロジェクトに統合しました。これが私のシナリオの簡単な説明です。

config/routes.rb には、次のエントリがあります...

resources :users
match '/profile', :to => 'users#show'

これが私の users_controller.rb の外観です...

class UsersController < ApplicationController
  before_filter :load_show_resource, :only => :show
  load_and_authorize_resource
  ...
  def show
  end
  ...
  private

    def load_show_resource
      @user = params[:id] ? User.find(params[:id]) : current_user
    end
end

current_user の ID が 1 の場合、このコードでは localhost:3000/users/1 にアクセスできますが、localhost:3000/profile にはアクセスできません。

このアクセスをブロックしている cancan capability.rb クラスのエントリを以下に示します - これは cannot セクションです。できないエントリをコメントアウトすると、両方の URL が機能します。

...
can [:show, :update], User, :id => user.id
cannot [:show, :update, :destroy], User do |u|
  u.site_id != user.site_id
end
....

params[:id] が存在するかどうかに関係なく、show アクションの before_filter に手動でロードされているリソースを使用できませんか?

興味深いことに、users コントローラー (以下を参照) を変更して、skip_load_and_authorize_resource :only => :show を使用し、手動で authorize! を呼び出すと、show アクションでは、両方の URL が機能します。また、cancan を完全に削除すると、両方の URL が機能します。

class UsersController < ApplicationController
  load_and_authorize_resource
  skip_load_and_authorize_resource :only => :show
  ...
  def show
    @user = params[:id] ? User.find(params[:id]) : current_user
authorize! :show, @user
  end
  ...
  private

    def load_show_resource
      @user = params[:id] ? User.find(params[:id]) : current_user
    end
end

それで、私の質問は、カンカンのドキュメントのオーバーライドの読み込みで説明されていることが、この状況で機能しないのはなぜですか?

ありがとう!

4

1 に答える 1

0
# controller

class UsersController < ApplicationController
  load_and_authorize_resource, :except => :show
  # skip_load_and_authorize_resource :only => :show
  ...
  def show
    @user = params[:id] ? User.find(params[:id]) : current_user
    authorize! :show, @user
  end
  ...
end

# ability.rb

can [:show, :update, :destroy], User do |u|
  u.id == user.id && u.site_id == user.site_id
end
于 2013-03-17T09:18:29.090 に答える