简体   繁体   中英

Cannot access action in Rails even with CanCanCan ability

I have the following:

questions_controller.rb
class QuestionsController < ApplicationController
  load_and_authorize_resource #cancancan

  def index
    authorize! :view_all, @questions
ability.rb
class Ability
  include CanCan::Ability

  def initialize(user)
    ...
    elsif user.content_creator
      can [:index, :read, :create, :update], Unit
      can [:index, :read, :create, :update, :view_all], Question
routes.rb
  resources :units do
    resources :questions, only: [:index]
Log
Started GET "/units/1/questions" for ::1 at 2018-10-29 13:37:15 -0400
Processing by QuestionsController#index as HTML
  Parameters: {"unit_id"=>"1"}
  User Load (8.0ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = $1  ORDER BY "users"."id" ASC LIMIT 1  [["id", 13]]
You are not authorized to access this page.
Redirected to http://localhost:3000/dashboard

I confirmed the user is content_creator . I even restarted the server. The user can update a Unit . They cannot view the index of questions in that unit however. Why not?

If I put can :manage, Question at the beginning of ability.rb , then it is still unauthorized. If I use can :manage, :all , then it works.

Cancancan ~> 1.10

I got rid of

# authorize! :view_all, @questions # prevents ContentCreators from viewing /units/1/questions

And changed

can :read, Question

To

can :show, Question

Everywhere else in ability.rb so only authorized viewers can see the index. This isn't a full answer however because it's still not clear why the original code did not work.

I was also in a similar situation, after looking around what I found is this:

Choosing actions

class ProductsController < ActionController::Base
  load_and_authorize_resource
  def discontinue
    # Automatically does the following:
    # @product = Product.find(params[:id])
    # authorize! :discontinue, @product
  end
end

according to the commented out text, cancancan by default expect the action name to equal the ability, in your case you'll have to create a new action called

def view_all

or else you'll have to create a sub rule for index.

Hope this helps.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM