CanCanCan throws a regular Rails error on an exception rather than a flash message like I specified
Asked Answered
R

2

12

I am using CanCanCan, Devise & Rolify.

My ApplicationController looks like this:

class ApplicationController < ActionController::Base
  # Prevent CSRF attacks by raising an exception.
  # For APIs, you may want to use :null_session instead.
  protect_from_forgery with: :exception
  before_filter :new_post

  rescue_from CanCan::AccessDenied do |exception|
    redirect_to root_url, :alert => exception.message
  end

  def new_post
    @post = Post.new
  end  

end

My routes.rb looks like this:

  authenticate :user, lambda { |u| u.has_role? :admin or :editor } do
    get 'newsroom', to: 'newsroom#index', as: "newsroom"
    get 'newsroom/published', to: 'newsroom#published'
    get 'newsroom/unpublished', to: 'newsroom#unpublished'    
  end

# truncated for brevity
  root to: "posts#index"

This is my ability.rb that is relevant:

elsif user.has_role? :member
    can :read, :all
    cannot :read, :newsroom

So when I am logged in as :member, and I try to go to /newsroom, I get this error:

NameError at /newsroom
uninitialized constant Newsroom

Rather than being redirected to the root_url with an :alert like I would have expected.

Not sure what's happening here.

Edit 1

For what it's worth, I only get this when I add this to my NewsroomController:

authorize_resource
Rexanna answered 8/12, 2014 at 9:48 Comment(2)
Does it provoke an error if you access /newsroom loggued as an admin ?Bloated
@Bloated yes it does provoke an error if I access /newsroom logged in as admin.Rexanna
R
2

It turns out that the issue was with the way I authorized my Newsroom Controller - because Newsroom was a non-restful controller (i.e. there was no model associated with Newsroom.

I had to add this to the top of my controller:

authorize_resource :class => false

As specified here: https://github.com/CanCanCommunity/cancancan/wiki/Non-RESTful-Controllers#alternative-authorize_resource

Rexanna answered 17/12, 2014 at 22:36 Comment(0)
A
2

I'm not very experienced in CanCan but I can see that you're rescuing from CanCan::AccessDenied whereas the exception is a NameError. Thus you shouldn't expect your rescue block to work.

I would say that you've probably misspelled 'Newsroom' somewhere or are accessing it where it isn't available.

Abbotsun answered 17/12, 2014 at 1:13 Comment(1)
The docs say for exception handling, we should rescue from CanCan::AccessDenied - github.com/CanCanCommunity/cancancan/wiki/Exception-HandlingRexanna
R
2

It turns out that the issue was with the way I authorized my Newsroom Controller - because Newsroom was a non-restful controller (i.e. there was no model associated with Newsroom.

I had to add this to the top of my controller:

authorize_resource :class => false

As specified here: https://github.com/CanCanCommunity/cancancan/wiki/Non-RESTful-Controllers#alternative-authorize_resource

Rexanna answered 17/12, 2014 at 22:36 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.