私は最近、承認のために 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
それで、私の質問は、カンカンのドキュメントのオーバーライドの読み込みで説明されていることが、この状況で機能しないのはなぜですか?
ありがとう!