我的能力档案
if user.has_role? :admin
can :manage, :all
else
can :manage, Company, :id => Company.with_role(:operator, user).pluck(:id)
...
end
我的公司控制人指数
def index
@companies = Company.with_role(:operator, current_user)
但是当我以操作公司的用户身份登录时,我无法访问该页面。 (即使Company.with_role(:operator,user)在控制台中返回一个关系!)
公司有代码。我不知道如何用cancan写这个:
Company.with_role(:operator, user).map{|o| o.codes}
但是wiki说如果我使用一个块,那么authorize_resource就不会设置实例变量@codes
,因为它不知道哪些对象属于用户。所以我不能用:
can :manage, Code => do |Code|
user.has_role? :operator, code.company
end
我正在寻找一种让我的CodesController能够做到的解决方案:
def index
if params[:company_id]
@keywords = Code.where(:company_id => params[:company_id])
end
以其他方式向用户显示他们拥有operator
角色的所有公司的所有代码。
答案 0 :(得分:0)
怎么样:
can :manage, Company do |company|
user.has_role? :operator, company
end
can :manage, Code do |code|
user.has_role? :operator, code.company
end
如果您没有对can定义使用块语法,则可以在CodesController中使用load_and_authorize_resource将索引过滤为仅当前用户可访问的索引。
<强>更新强> 因为这使用了块语法,CanCan无法使用load_resource确定要加载哪些对象(因为它想使用SQL语法)。如果你可以重写它不使用块语法,那么你会很好。如果必须使用角色类型逻辑,则可以在控制器的索引方法中添加类似于以下内容的代码:
@codes = Code.all.select {|code| can?(:manage, code)}
或者如果你想绕过这种情况下提高效率的能力
@codes = Company.with_role(:operator, @current_user).codes
答案 1 :(得分:0)
def index
if params[:company_id]
@codes = Company.with_role(:operator, current_user).where(:id => params[:company_id]).map{|o| o.keywords}.flatten
else
@codes = Company.with_role(:operator, current_user).map{|operator| operator.keywords}.flatten
end
end