0

我想根据嵌套资源的属性过滤模型,例如:

can :read, Model, has_many_relation: { attribute: attr }

使用这种形式的块的问题:

can :read, Model do |obj|
    obj.has_attribute(attr)
end

是该权限只能在获取单个模型时使用(调用加载#index操作时忽略该权限)。

如何使用基于 has_many 关系的条件过滤模型?

4

3 回答 3

2

我已经使用 CanCan 多年了,我只是把它整理出来。伪代码有点棘手,但希望这能让你到达那里。

can :read, Model, Model.joins(:has_many_relation).where(has_many_table: { attribute: attr }) do |model|
  model.has_many_relation.pluck(:attribute).include?(attr)  
end

一个更具体的示例(仅读取用户user.widgets范围内的小部件)可能更容易理解:

can :read, Widget, user.widgets do |widget|
  user.widgets.include?(widget)
end

一般的想法是你必须同时包含一个SQL 查询(用于查询所有可访问的模型)一个块(用于检查单个模型的权限)。

而且,作为记录,我们一直在寻找的示例实际上已经在docs中。

于 2013-07-08T17:49:41.853 回答
0

You could use a scope if you are using CanCan >= 1.6.

can :read,
  Model,
  Model.joins(:has_many_relation)
       .where(:has_many_table => { :attribute => attr }) 
于 2013-06-08T00:14:43.820 回答
0

为了通过一个属性 un a has_many 关系进行过滤,基本的条件散列就可以了。

用于提出问题的第一个示例有效:

can :read, Model, has_many_relation: { attribute: attr }

只需确保模型具有相应的 has_many 关系并且 has_many 表包含属性引用的列:

于 2013-09-11T15:56:30.440 回答