我使用CanCanCan进行授权。基本上我想要发生的是未登录的用户可以访问Home#Index
,但他们需要登录Home#Dashboard
。
我有这条路线:
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'
导致这种情况的原因是什么?
修改1
经过一些调试后,我现在意识到这似乎与我authorizing
的动作不受ActiveRecord资源支持这一事实有关。
换句话说,一旦我将:dashboard
添加到exception
列表中,就像这样:
authorize_resource except: [:index, :dashboard]
skip_authorization_check only: [:index, :dashboard]
有效。该页面像魅力一样加载。
所以我猜真正的问题是,如何授权/锁定不是ActiveRecord模型的资源?
答案 0 :(得分: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的这种方法的基础。