Rails cancan可以与before_filter一起发布

时间:2013-03-17 06:14:17

标签: ruby-on-rails ruby-on-rails-3 cancan

我最近将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类中阻止此访问的条目如下所示 - 它是can not section。如果我注释掉无法输入,则两个网址都有效。

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

不管params [:id]是否存在,cancan是否应该使用在before_filter中手动加载的资源进行show动作?

有趣的是,如果我修改我的用户控制器(见下文)以使用skip_load_and_authorize_resource:only =&gt; :显示并手动调用授权!在节目动作中,两个网址都有效。此外,如果我完全删除cancan,两个网址都可以使用。

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 documentation的覆盖加载中解释的内容在这种情况下不起作用?

谢谢!

1 个答案:

答案 0 :(得分: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