I am trying to serve up some resources on a custom route, but an being denied access via my CanCan gem.
PlaysController with custom route: upcoming_plays
class PlaysController < ApplicationController
load_and_authorize_resource
def upcoming_plays
@plays = Play.where("date_of_play >= ?",Time.now ).order(date_of_play: :desc )
end
#...
end
app/views/plays/upcoming_plays.html.erb
<!-- This displays links to plays/ID for play occurring in the future-->
<div id="show-all-plays">
<% @plays.each do |current_play| %>
<%= render partial: "layouts/play_link" ,
locals: {play: current_play} %>
<% end %>
</div>
config/routes.rb
Rails.application.routes.draw do
get 'plays/upcoming_plays', :as => 'upcoming_plays', :path=>'upcoming_plays'
#...
end
app/models/ability.rb
class Ability
include CanCan::Ability
def initialize(user)
if user != nil and user.role == 'admin'
can :manage, :all
else
can :read, :all
end
end
end
Received error on navigation to /upcoming_plays.html :
You are not authorized to access this page.
and it blocks me from viewing that page with a redirect to root page
I am not sure if CanCan believes I am attempting to manage/modify the Plays Model, but all I am trying to do is read the values from the DB. Any ideas? Thank you for the help!
Edit: Rokibul Hasan suggested adding
skip_authorize_resource :only => :upcoming_plays
to the plays controller. Which worked! However this seems like a hack. What if I want to add the ability for an admin to edit things on this page? I don't want the the forbidden actions to be available to everyone. Seems like this could be an issue, any ideas?
Seems problem is in your ability class, Can you please rewrite you ability
as following
class Ability
include CanCan::Ability
def initialize(user)
user ||= User.new
if user.role == 'admin'
can :manage, :all
else
can :read, :all
end
end
end
load_and_authorize_resource
can authorize automatically for every action in your controller. For an alternate solution you can add following code to your controller to skip upcoming_plays
from authorize.
skip_authorize_resource :only => :upcoming_plays