我想根据嵌套资源的属性过滤模型,例如:
can :read, Model, has_many_relation: { attribute: attr }
使用这种形式的块的问题:
can :read, Model do |obj|
obj.has_attribute(attr)
end
是该权限只能在获取单个模型时使用(调用加载#index操作时忽略该权限)。
如何使用基于 has_many 关系的条件过滤模型?
我想根据嵌套资源的属性过滤模型,例如:
can :read, Model, has_many_relation: { attribute: attr }
使用这种形式的块的问题:
can :read, Model do |obj|
obj.has_attribute(attr)
end
是该权限只能在获取单个模型时使用(调用加载#index操作时忽略该权限)。
如何使用基于 has_many 关系的条件过滤模型?
我已经使用 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中。
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 })
为了通过一个属性 un a has_many 关系进行过滤,基本的条件散列就可以了。
用于提出问题的第一个示例有效:
can :read, Model, has_many_relation: { attribute: attr }
只需确保模型具有相应的 has_many 关系并且 has_many 表包含属性引用的列: