我想要缓存Post
视图,但视图取决于当前用户的权限(例如,我只显示“编辑”链接,如果current_user.can?(:edit, @post)
)
所以我希望我的缓存键包含当前用户的CanCan能力的表示,这样当用户的能力改变时我可以使缓存无效
SO:如何获得代表当前用户能力的字符串,以便具有相同能力的2个不同用户生成相同的“能力字符串”?
我已经尝试了user.ability.inspect
,但这对于具有相同能力的不同用户不会产生相同的字符串
答案 0 :(得分:9)
编辑:CanCanCan修订
从CanCanCan版本1.12(CanCan的社区延续版)开始,Ability.new(user).permissions
返回一个包含给定用户所有权限的哈希值。
上一个回答(CanCan):
这可能有点复杂......但在这里......
如果您将指定的User传递给CanCan所需的Ability模型,您可以使用instance_variable_get访问该用户角色的定义,然后将其分解为您想要的任何字符串值。
>> u=User.new(:role=>"admin")
>> a=Ability.new(u)
>> a.instance_variable_get("@rules").collect{
|rule| rule.instance_variable_get("@actions").to_s
}
=> ["read", "manage", "update"]
如果您想知道这些规则所针对的模型,您可以访问@subjects实例变量来获取其名称..
这是我与之合作的能力的模型布局(pp)
Ability:0x5b41dba @rules=[
#<CanCan::Rule:0xc114739
@actions=[:read],
@base_behavior=true,
@conditions={},
@match_all=false,
@block=nil,
@subjects=[
User(role: string)]>,
#<CanCan::Rule:0x7ec40b92
@actions=[:manage],
@base_behavior=true,
@conditions={},
@match_all=false,
@block=nil,
@subjects=[
Encounter(id: integer)]>,
#<CanCan::Rule:0x55bf110c
@actions=[:update],
@base_behavior=true,
@conditions={:id=>4},
@match_all=false,
@block=nil,
@subjects=[
User(role: string)]>
]
答案 1 :(得分:7)
我想将自己的能力发送给JS,并且关注这篇文章,这里是我的帮助方法,您可以使用它将用户能力转换为控制器中的数组。然后我在数组上调用.to_json并将其传递给javascript。
def ability_to_array(a)
a.instance_variable_get("@rules").collect{ |rule|
{
:subject => rule.instance_variable_get("@subjects").map { |s| s.name },
:actions => rule.instance_variable_get("@actions").map { |a| a.to_s }
}
}
end
这是我实现can()方法的Backbone.js模型:
var Abilities = Backbone.Model.extend({
can : function(action, subject)
{
return _.some(this.get("abilities"), function(a) {
if(_.contains(a["actions"], "manage") && _.contains(a["subject"], "all")) return true;
return _.contains(a["actions"], action) && _.contains(a["subject"], subject);
});
}
});