gpt4 book ai didi

ruby-on-rails - cancan 不评估实例级别的能力检查

转载 作者:行者123 更新时间:2023-12-03 06:04:09 26 4
gpt4 key购买 nike

我正在尝试将 cancan 合并到我的第一个 Ruby on Rails 应用程序中。

我在入门时遇到问题...这肯定是一些基本问题。

我的应用程序有一个项目列表,用户可能有权也可能没有权限查看其中任意数量的项目。

我将其添加到我的 ProjectsController 中:

class ProjectsController < ApplicationController
load_and_authorize_resource

我的初始化方法如下所示:

  def initialize(user)
user ||= User.new # guest user
puts "******** Evaluating cancan permissions for: " + user.inspect
can :read, Project do |project|
puts "******** Evaluating project permissions for: " + project.inspect
# project.try(project_users).any?{|project_user| project_user.user == user}
1 == 1 #POC test!
end
end

当我看到这个时,会出现项目索引页面,但没有列出任何项目。

我有两个问题:

  1. 不应该出现所有项目吗,因为所有项目都返回 true项目?
  2. 第二个puts语句没有写入rails服务器控制台,但第一个是。这是为什么???

如果我将初始化方法更改为:

  def initialize(user)
user ||= User.new # guest user
puts "******** Evaluating cancan permissions for: " + user.inspect
can :read, Project
end

...我看到的所有项目都符合我的预期

如果我删除 can :read, Project 行,我会在尝试访问项目索引页时遇到安全异常......这也是我所期望的。

最佳答案

仅当项目实例可用时才会评估传递给 :read 功能的 block (@project)。因为您正在讨论索引操作,所以只有集合可用(@projects)。这解释了为什么你的第二个 put 语句永远不会出现。为了限制索引操作,您需要将条件哈希传递到 can 方法中,或者使用作用域(除了 block 之外)。 Github 上的 CanCan wiki 中清楚地概述了所有这些信息。

因此,看跌期权问题是可以解释的。没有意义的是没有项目显示。在评估索引操作时,CanCan 实际上会默认完全忽略该 block 。这意味着您的能力本质上是can :read, Project(即使在第一个示例中)对于索引操作。

我有兴趣让您尝试添加一个简单的范围,只是为了看看它是否有效。尝试:

can :read, Project, Project.scoped do |project|
true
end

然后看看索引操作会发生什么。

编辑:

鉴于您现在可以在索引中查看项目,似乎您需要将范围以及 block 传递到功能中。请阅读this Github issue其中 Ryan 解释了为什么不根据索引操作评估该 block 。

Blocks are only intended to be used for defining abilities based on an object's attributes. [...] That is the only case when a block should be used because the block is only executed when an object is available. All other conditions should be defined outside the block.

请记住,如果您的能力对于条件散列而言不太复杂,则应该使用它。条件散列在 this CanCan wiki page on Github. 上进行了解释。如果您确实需要范围,则需要传入范围和 block 。假设您具有上面显示的能力。

  1. 在索引操作中,CanCan 将忽略该 block ,因为 Project 对象 (@project) 不可用。相反,它将返回给定范围内的项目,在本例中为 Project.scoped (即所有项目)。
  2. 在显示操作中,@project 可用,因此 CanCan 将评估该 block ,并在该 block 评估为 true 时允许该操作。

因此,您需要传递两者的原因是 CanCan 可以同时处理索引和显示操作。在大多数情况下,您的 block 将定义与范围相同的内容,只有 block 将用 Ruby 编写,而您的范围将使用 Rails 的 ActiveRecord 语法编写。您可以在这里了解更多信息:Defining Abilities with Blocks .

关于ruby-on-rails - cancan 不评估实例级别的能力检查,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15704730/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com