以正确的方式使用cancan

时间:2011-11-22 08:34:08

标签: ruby-on-rails cancan

我有一定的要求,根据用户的类型,视图具有不同的内容。假设我有用户控制器的索引操作。然后我可以使用cancan来授权这样的动作

authorize! :index, @users

此外,为了过滤内容,我还有其他授权,例如

if can :view_all,User

进一步授权,如

if can :view_some,User将需要另一个。

这将导致很多条件。而不是这个,我可以使用像

这样的简单条件
If the user is with view_all access show him all 
else if the user is with view_some access show him some
else access denied

Cancan需要一个额外的查询,不是吗?我可能以错误的方式使用cancan。需要一些建议。

以下是我的ability.rb文件的粗略片段

    can :index, User do |user1|
      role.accesses.include?(Access.where(:name => "access1").first) || role.accesses.include?(Access.where(:name => "access2").first)
    end

    can :view_all, User do |user1|
      role.accesses.include?(Access.where(:name => "access1").first) 
    end

    can :view_some, User do |user1|
      role.accesses.include?(Access.where(:name => "access2").first) 
    end

1 个答案:

答案 0 :(得分:0)

  

Cancan需要一个额外的查询吗?

组合能力时,cancan将使用单个查询。

如果你看看规格,例如。 spec/cancan/model_adapters/active_record_adapter_spec.rb,你会发现这样的规格:

it "should fetch any articles which are published or secret", focus: true do
  @ability.can :read, Article, :published => true
  @ability.can :read, Article, :secret => true
  article1 = Article.create!(:published => true, :secret => false)
  article2 = Article.create!(:published => true, :secret => true)
  article3 = Article.create!(:published => false, :secret => true)
  article4 = Article.create!(:published => false, :secret => false)
  Article.accessible_by(@ability).should == [article1, article2, article3]
end

如果启用SQL日志记录,您将看到该查询结合了以下条件:

Article Load (0.2ms)  
SELECT "with_model_articles_95131".* 
FROM "with_model_articles_95131" 
WHERE (("with_model_articles_95131"."secret" = 't') 
  OR ("with_model_articles_95131"."published" = 't'))