2016-11-01 1 views
1

Я использую CanCanCan для авторизации. В принципе, я хочу, чтобы пользователи не регистрировались, пользователи могут получить доступ к Home#Index, но они должны быть зарегистрированы для Home#Dashboard.uninitialized constant Home - брошен CanCanCan для не-db поддерживаемого ресурса

У меня есть этот маршрут:

get 'dashboard', to: 'home#dashboard', as: :dashboard 

Это мой HomeController:

class HomeController < ApplicationController 
    authorize_resource except: [:index] 
    skip_authorization_check only: [:index] 
    layout 'marketing', only: [:index] 

    def index 
    end 

    def dashboard 
    end 
end 

Это мой application_controller.rb:

class ApplicationController < ActionController::Base 
    protect_from_forgery with: :exception 
    before_action :configure_permitted_parameters, if: :devise_controller? 
    check_authorization :unless => :devise_controller? 

    rescue_from CanCan::AccessDenied do |exception| 
    respond_to do |format| 
     format.json { head :forbidden } 
     format.html { redirect_back(fallback_location: root_path, flash: { danger: exception.message }) } 
    end 
    end 

    protected 

    def configure_permitted_parameters 
    devise_parameter_sanitizer.permit(:accept_invitation, keys: [:first_name, :last_name, :phone]) 
    end 
end 

Однако, когда я иду в /dashboard, это ошибка, которую я получаю:

NameError - uninitialized constant Home: 
    activesupport (5.0.0.1) lib/active_support/dependencies.rb:550:in `load_missing_constant' 
    activesupport (5.0.0.1) lib/active_support/dependencies.rb:203:in `const_missing' 
    activesupport (5.0.0.1) lib/active_support/inflector/methods.rb:268:in `block in constantize' 
    activesupport (5.0.0.1) lib/active_support/inflector/methods.rb:266:in `constantize' 
    activesupport (5.0.0.1) lib/active_support/core_ext/string/inflections.rb:66:in `constantize' 

Что может быть причиной этого?

Edit 1

После некоторой отладки, я теперь понимаю, что это, кажется, связано с тем, что действия я являюсь authorizing не поддерживается ресурсом ActiveRecord.

Другими словами, как только я добавить :dashboard к exception списку, например, так:

authorize_resource except: [:index, :dashboard] 
    skip_authorization_check only: [:index, :dashboard] 

Он работает. Страница загружается как очарование.

Итак, я думаю, что реальная проблема заключается в том, как мне разрешить/заблокировать ресурс, который не является моделью ActiveRecord?

+1

у вас есть опечатка в имени файла, который определяет 'HomeController'? , Вы перезапустили сервер?, Я просто догадываюсь, но это может быть что-то вроде этого. Думаю, это больше связано с опечаткой. – fanta

+0

Я только что перезапустил сервер и по-прежнему ту же ошибку. Кроме того, t опечатка, потому что, когда я перехожу к 'home # index', это работает. Это мой' unauthenticated root_path', и это работает отлично. Это просто 'home # dashboard', это не так. Имеет ли значение, что' Home' не коррелирует с модель в моей БД? Будет ли CanCanCan иметь проблемы с «авторизацией ресурса», который не является ресурсом db? – marcamillion

+0

Я думаю, что вы правильно, возможно, это связано с тем, что у вас нет модели для дома, посмотрите здесь https://github.com/CanCanCommunity/cancancan/wiki/Non-RESTful-Controllers, в которой рассказывается, как справляться с этими случаями. – fanta

ответ

0

Похоже, что проблема связана с моей попыткой authorize_resource для ресурса, который не является ресурсом, поддерживающим модель ActiveRecord.

Так что мне пришлось удалить authorize_resource с начала контроллера, а затем authorize! каждое отдельное действие. Затем мне пришлось добавить это правило к ability.rb.

Теперь мой HomeController выглядит следующим образом:

class HomeController < ApplicationController 
    skip_authorization_check only: [:index] 
    layout 'marketing', only: [:index] 


    def index 
    end 

    def dashboard 
    authorize! :read, :dashboard 
    end 
end 

Тогда в моем ability.rb, у меня есть это:

class Ability 
    include CanCan::Ability 

    def initialize(user) 
    user ||= User.new # guest user (not logged in) 

    can :manage, User, id: user.id 
    can :read, :dashboard if user.has_any_role? :admin, :coach, :player 
    end 
end 

Где я должен был жёстко во всей roles в моей дб.

То, что я ДЕЙСТВИТЕЛЬНО хотел сделать, это просто выполнить проверку, чтобы проверить, не вступил ли пользователь в систему, но по какой-либо причине он все время терпел неудачу на всех проверках user_signed_in?.

В идеале я хотел бы сделать что-то вроде:

can :read, :dashboard if current_user? 

Или:

can :read, :dashboard if user.user_signed_in? 

Но оба эти не работали, и дал мне вариации следующей ошибки:

undefined local variable or method `current_user' for #<Ability:0x007faca14db2c8> 

или:

undefined method `user_signed_in?' for #<User:0x007fac86b2a9c8> 

Если у вас есть предложения по тому, как я могу это достичь, пожалуйста, оставьте комментарий или напишите новый ответ, и я приму его. До тех пор, я думаю, это будет делать :(

Основа этого подхода, который я нашел в вики CanCanCan о managing Non-Restful Controllers.