我正在尝试限制用户未创建的项目的访问权限。这似乎与以下工作正常:
if user.has_role?(:Student)
can :create, Project
can :manage, Project, :user_id => user.id
end
(旁边问题:有没有更好的方式来写这个?^^)
但是,我仍然可以访问URL:/ users / 5 / projects
我无法按预期看到项目。我宁愿它告诉我,我无法访问该页面,并重定向。我在我的应用程序控制器中有这个:
rescue_from CanCan::AccessDenied do |exception|
redirect_to root_url, :alert => exception.message
end
但我没有收到重定向或错误消息。我是否需要在能力上添加其他东西才能使其发挥作用?
我在ProjectsController和UsersController中都有load_and_authorize_resource
。
为了记录,我的路线看起来像这样:
resources :users do
resources :projects
end
答案 0 :(得分:1)
试试这个
if user.has_role?(:Student)
can :create, Project
can :manage, Project do |P|
user && P.user == user
end
它将检查当前用户是否拥有该项目。如果他不拥有该项目,那么他将无法对其进行修改。
第一个条件是检查user
对象是否存在,你也可以在那里使用异常处理程序。这是一个例子:
comment.try(:user) == user
答案 1 :(得分:0)
如果要在用户无法读取当前集合中的任何项目时启用重定向行为,请覆盖索引操作并添加额外的强制执行:
def index
# @projects is loaded by the CanCan before filter load_and_authorize_resource
unless @projects.any?{|project| can?(:read, project)}
raise CanCanAccessDenied.new("no project readable there", :read, Project)
end
end
在类似索引(集合)的控制器操作中,CanCan通过authorize :read, ModelClass
强制执行ACL
https://github.com/ryanb/cancan/wiki/Checking-Abilities请参阅“按类检查”部分
如您所知,如果用户有可能:读取任何ModelClass实例(即使这些实例尚不存在),查询authorize :action, ModelClass
将授权。
鉴于您的网址/users/5/projects
和路由resources :users do resources :projects end
我相信此操作是针对特定用户的项目的索引。因此,给定can :manage, Project, :user_id => user.id
,CanCan索引操作将授权,因此用户可以存在项目:read as such =>授权。稍后在视图中我相信你授权每个特定的项目实例can? :read, project
,并且它们会被过滤,因此页面仍然是空的。