使用has_many关系过滤模型

时间:2013-06-05 19:58:47

标签: ruby-on-rails activerecord cancan

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

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

使用此表单块的问题:

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

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

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

3 个答案:

答案 0 :(得分: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查询(用于查询所有可访问的模型),一个块(用于检查单个模型的权限)

而且,为了记录,我们一直在寻找的例子实际上已经在the docs

答案 1 :(得分:0)

如果您使用CanCan> = 1.6。

,则可以使用范围
can :read,
  Model,
  Model.joins(:has_many_relation)
       .where(:has_many_table => { :attribute => attr }) 

答案 2 :(得分:0)

为了按属性过滤一个has_many关系,基本的hash of conditions就可以了。

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

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

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