我最近将 cancan (1.6.9) 集成到我的 Rails (3.2.10) 项目中以进行授权,并且在 before_filter 中手动加载资源时遇到问题。这是我的场景的简要描述。
在 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 ability.rb 类中阻止此访问的条目如下所示 - 它是 cancan 部分。如果我注释掉无法条目,则两个网址都有效。
...
can [:show, :update], User, :id => user.id
cannot [:show, :update, :destroy], User do |u|
u.site_id != user.site_id
end
....
不管 params[:id] 是否存在,不应该使用在 before_filter 中手动加载的资源来进行 show 操作吗?
有趣的是,如果我修改我的用户控制器(见下文)以使用 skip_load_and_authorize_resource :only => :show 并手动调用授权!在表演动作中,两个网址都有效。此外,如果我完全删除 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
所以,我的问题是为什么cancan 文档中的 Override loading 中解释的内容在这种情况下不起作用?
谢谢!