Should I skip authorization, with CanCan, of an action that instantiates a resource?
Posted
by irkenInvader
on Stack Overflow
See other posts from Stack Overflow
or by irkenInvader
Published on 2010-05-14T03:45:32Z
Indexed on
2010/05/14
3:54 UTC
Read the original article
Hit count: 257
ruby-on-rails
|cancan
I am writing a web app to pick random lists of cards from larger, complete sets of cards. I have a Card model and a CardSet model. Both models have a full RESTful set of 7 actions (:index, :new, :show, etc). The CardSetsController has an extra action for creating random sets: :random
.
# app/models/card_set.rb
class CardSet < ActiveRecord::Base
belongs_to :creator, :class_name => "User"
has_many :memberships
has_many :cards, :through => :memberships
# app/models/card.rb
class Card < ActiveRecord::Base
belongs_to :creator, :class_name => "User"
has_many :memberships
has_many :card_sets, :through => :memberships
I have added Devise for authentication and CanCan for authorizations. I have users with an 'editor' role. Editors are allowed to create new CardSets. Guest users (Users who have not logged in) can only use the :index
and :show
actions. These authorizations are working as designed. Editors can currently use both the :random
and the :new
actions without any problems. Guest users, as expected, cannot.
# app/controllers/card_sets_controller.rb
class CardSetsController < ApplicationController
before_filter :authenticate_user!, :except => [:show, :index]
load_and_authorize_resource
I want to allow guest users to use the :random
action, but not the :new
action. In other words, they can see new random sets, but not save them. The "Save" button on the :random
action's view is hidden (as designed) from the guest users. The problem is, the first thing the :random
action does is build a new instance of the CardSet model to fill out the view. When cancan tries to load_and_authorize_resource
a new CardSet, it throws a CanCan::AccessDenied exception. Therefore, the view never loads and the guest user is served a "You need to sign in or sign up before continuing" message.
# app/controllers/card_sets_controllers.rb
def random
@card_set = CardSet.new( :name => "New Set of 10", :set_type => "Set of 10" )
I realize that I can tell load_and_authorize_resource
to skip the :random
action by passing :except => :random
to the call, but that just feels "wrong" for some reason.
What's the "right" way to do this? Should I create the new random set without instantiating a new CardSet? Should I go ahead and add the exception?
© Stack Overflow or respective owner