我正在使用 Ryan Bate 的 CanCan gem 来定义能力,但一些基本功能失败了。我有一个 Product 模型和 Products Controller ,其中我的索引操作如下所示:
def index
@req_host_w_port = request.host_with_port
@products = Product.accessible_by(current_ability, :index)
end
当我尝试使用
accessible_by
方法检索产品时出现错误,出现此错误:Cannot determine SQL conditions or joins from block for :index Product(id: integer, secret: string, context_date: datetime, expiration_date: datetime, blurb: text, created_at: datetime, updated_at: datetime, owner_id: integer, product_type_id: integer, approved_at: datetime)
我的能力课是这样的:
can :index, Product do |product|
product && !!product.approved_at
end
这似乎是一个非常简单的例子,所以我很惊讶它失败了,想知道我是否忽略了一些简单的东西(即盯着我的代码太久)。
我做了更多的探索并进行了一个简单的测试。如果您查看下面的代码,您会发现一个示例可以正常工作,而一个示例在实际上应该做同样的事情时却失败了。
# This works
can :index, Product, :approved_at => nil
# This fails
can :index, Product do |product|
product && product.approved_at.nil?
end
所以问题似乎在于 CanCan 处理这些块的方式。我深入到库中,找到了错误发生的地方——在 CanCan 的能力类定义中:
def relevant_can_definitions_for_query(action, subject)
relevant_can_definitions(action, subject).each do |can_definition|
if can_definition.only_block?
raise Error, "Cannot determine SQL conditions or joins from block for #{action.inspect} #{subject.inspect}"
end
end
end
所以我检查了这个
only_block?
方法是什么。如果 can 定义有一个块但没有条件,则该方法返回 true,这对我来说没有意义,因为块的重点是在块中定义条件,因为它们对于以下语法来说太复杂了:can :manage, [Account], :account_manager_id => user.id
对这个问题的任何见解都会很棒!我还在 CanCan github 页面上提交了一个问题,但我已经到了可能需要放弃库的地步。但是,我知道很多人都成功地使用了 CanCan,这是如此基本的功能,我想我一定是做错了什么。特别是因为 git repo 是在 3 天前更新的,并且 Ryan Bates 在自述文件中提到了 Rails 3 支持。
谢谢!
最佳答案
好的,所以我浏览了 wiki,看到 accessible_by
在定义块时不起作用。有这个限制并且没有在 README 中提到它似乎有点奇怪,但至少我知道这是库的限制,而不是我或 Ryan Bates 代码中的错误。对于那些有兴趣的人,上面定义我的能力的正确方法如下:
# will fail
can :index, Product do |product|
product && product.approved_at.nil?
end
# will pass
can :index, Product
cannot :index, Product, :approved_at => nil
关于ruby-on-rails - 在 CanCan 中使用块来定义能力会引发异常,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/3557091/