Rails_admin与Cancan结合使用时无法捕获重定向的访问拒绝异常

9

我正在使用Rails 5、rails_admin、devise和cancancan。

一切都正常,但当访问被拒绝时,会显示一个“您无权访问此页面”的错误屏幕。

我想重定向到root_path,我一直在查找,发现我只需要在app/controllers/application_controller.rb中编写以下代码:

class ApplicationController < ActionController::Base    
    rescue_from CanCan::AccessDenied do |exception|
        redirect_to root_path, :alert => exception.message
    end
end

我已经尝试了,但是仍然收到未授权的错误信息。它没有重定向。

我认为代码的其余部分必须没问题,因为它能够工作,只是没有重定向到任何地方。

#config/initializers/rails_admin.rb
config.authorize_with :cancan
config.current_user_method(&:current_user)

.

#app/models/ability.rb
class Ability
    include CanCan::Ability

    def initialize(user)

    user ||= User.new # guest user (not logged in)
    if user.admin
        can :access, :rails_admin       # only allow admin users to access Rails Admin
        can :dashboard           
        can :manage, :all
    else
        can :read, :all                   # allow everyone to read everything
    end
  end
end

我看到很多人询问相同的问题,但是他们都没有得到答案。我找到了一个有3个回答的问题,但我不理解被接受的解决方案,因为没有真正解释任何解决方案: Cancan + Devise rescue_from not catching exception

2个回答

14

看起来ApplicationController默认并不是RailsAdmin::MainController的父类。所以,当RailsAdmin::MainController抛出CanCan::AccessDenied异常时,它实际上并没有接触到ApplicationController,救援块也不会启动。

你可以在rails_admin.rb配置块中显式声明ApplicationControllerRailsAdmin::MainController的父类:

config.parent_controller = 'ApplicationController' 

是的 - 我的问题也有解决方案。使用 rails_admin (1.1.1)。 - SerKnight
对我来说起作用了,我从0.8.0升级到了2.0.2。 - Deepak Mahakale
这个答案对我也起作用了。谢谢。 - Mugirase Emmanuel

5
您还可以通过扩展rails_admin控制器来实现此目的。这是猴子补丁,但如果您不想由于特定原因设置父控制器为,则可能会很有用。
将以下内容添加到config/initializers/rails_admin_cancan.rb文件中。
require 'rails_admin/main_controller'

module RailsAdmin

  class MainController < RailsAdmin::ApplicationController
    rescue_from CanCan::AccessDenied do |exception|
      flash[:alert] = 'Access denied.'
      redirect_to main_app.root_path
    end
  end
end

这个方法非常有效!接受的解决方案在Rails Admin的仪表板上引发了一个访问被拒绝的错误,因为没有进行授权。可能是因为我的applications_controller中有一个check_authorization,而特定的Rails Admin资源中没有load_and_authorize_resource。尽管如此,您的建议确实起作用了。 - Jul
这是更好的解决方案!改变父控制器也给我带来了其他问题! - Markus Andreas

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接