ruby-on-railscancancan

Red Rails screen instead of flash message: CanCan::AccessDenied in RailsAdmin::MainController#dashboard


I use Devise, CanCanCan and rails_admin. With accessibility everything is OK, but I fail to get a flash message and redirect to root_path and getting the screen below. Any ideas, hints on how I could get flash message instead of this? Other flash messages, both alerts and notifications display OK. Thanks a lot. Rails server red error screen

My ApplicationController is:

class ApplicationController < ActionController::Base
protect_from_forgery with: :exception
before_action :authenticate_user!

def after_sign_in_path_for(resource)
  stored_location_for(resource) || welcome_path_url
end

rescue_from CanCan::AccessDenied do |exception|
  respond_to do |format|
    format.json { head :forbidden, content_type: 'text/html' }
    format.html { redirect_to main_app.root_url, notice: exception.message }
    format.js   { head :forbidden, content_type: 'text/html' }
  end
end
end

rails_admin.rb

RailsAdmin.config do |config|

### Popular gems integration

## == Devise ==
config.authenticate_with do
  warden.authenticate! scope: :user
end
config.current_user_method(&:current_user)

## == CancanCan ==
# config.authorize_with :cancancan
config.authorize_with do
  redirect_to main_app.root_path unless current_user.superuser ==true
end
<....>
end

ability.rb

class Ability
  include CanCan::Ability

  def initialize(user)
    # Define abilities for the passed in user here. For example:
    #
    user ||= User.new # guest user (not logged in)
    if user.superuser?
      can :manage, :all
      cannot :access, :rails_admin
      cannot :manage, :dashboard
    end
    if user.office?
      cannot :access, :rails_admin
      cannot :manage, :dashboard
      can :read, :all
    end
  end
end

EDIT: The working answer is marked. Also I should define status variable like this:

  def status
    @user_role ||= User.new(read_attribute(:user_role))
  end

in my User model.


Solution

  • It seems RailsAdmin::MainController isn't derived from ApplicationController you defined on the app to catch the exceptions raised on its subclass.

    You need to explicitly add the config to use another parent controller like below. Please find the related gem documentation here:

     # in config/initializers/rails_admin.rb
    
    config.parent_controller = 'ApplicationController'
    

    This stack overflow answer as well might help you.