简体   繁体   中英

Rails CanCanCan ability issue with model-less controller

I have a simple controller method: WelcomeController#dashboard that is intended to be the landing page AFTER a user logs in (the user has the role of 'manager' for this test).

I'm starting out simple, so there isn't much to this controller yet controllers/welcome_controller.rb :

class WelcomeController < ApplicationController
  skip_authorize_resource only: :index
  authorize_resource class: false, only: [:dashboard]

  skip_before_action :authenticate_user!, only: [:index]
  layout 'external', only: [:index]

  def index; end

  def dashboard; end
end

So, I've got CanCanCan installed and in my models/ability.rb file:

class Ability
  include CanCan::Ability

  def initialize(user)
    user ||= User.new # guest user (not logged in)
    if user.admin?
      can :manage, :all
      can :access, :rails_admin
    elsif user.manager?
      can :read, Lesson
      can :access, :dashboard
      can :modify, Company
    elsif user.user?
      can :read, Lesson
    else
      can :read, :root
    end
  end
end

However, my Rspec test is failing and I cannot figure out why. The code in spec/controllers/welcome_controller_spec.rb is:

require 'rails_helper'
require 'cancan/matchers'

RSpec.describe WelcomeController, type: :controller do
  describe 'GET #index' do
    it 'returns http success' do
      get :index
      expect(response).to have_http_status(:success)
    end
  end

  describe 'GET #dashboard' do
    it 'manager routes to dashboard after login' do
      company = Company.create!(name: 'ACME', domain: 'acme.com')
      user = User.create!(email: 'test@test.com', password: 'password', password_confirmation: 'password', company_id: company.id, role: 1)
      sign_in user
      get :dashboard
      expect(response).to have_http_status(:success)
    end

    it 'user does not route to dashboard after login' do
      user = create(:user)
      sign_in user
      expect { get :dashboard }.to raise_error(CanCan::AccessDenied)
    end
  end
end

Which results in this error:

Failures:

  1) WelcomeController GET #dashboard manager routes to dashboard after login
     Failure/Error: get :dashboard

     CanCan::AccessDenied:
       You are not authorized to access this page.
     # ./spec/controllers/welcome_controller_spec.rb:17:in `block (3 levels) in <top (required)>'

I find it interesting that only the "manager routes to dashboard after login" test is what is failing, since the 3rd test for the user passes without an issue even though I'm using the same :dashboard call.

I'd be grateful for any help/suggestions.

Thanks!

my understanding there is no action with alias_action name :access , refering from this link (please correct me if it's not correct), but you can create custom action with alias_action

your ability.rb

class Ability
  include CanCan::Ability

  def initialize(user)
    # here you create alias_action
    alias_action :create, :read, :update, :destroy, to: :access
    user ||= User.new # guest user (not logged in)
    if user.admin?
      can :manage, :all
      can :access, :rails_admin
    elsif user.manager?
      can :read, Lesson
      can :access, :dashboard
      can :modify, Company
    elsif user.user?
      can :read, Lesson
    else
      can :read, :root
    end
  end
end

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