25345
cancancanのgemを用いて権限管理を前提としたサービスを開発しております。

仮に以下のロールがあったとします。

admin_user  
hoge_user  
piyo_user

これらのユーザーで

admin_userはすべての情報を知ることができ、  
それ以外のユーザーはcurrent_userに関連する情報のみ見ることができる

といった機能を開発したいです。

こういう場合に  
私の理解では、Controllerにその処理を書くには

```

    
    if current_user.admin?
      Article.all
    else
      current_user.articles
    end
    
    
```

といった処理になるかと思います。

これはこれでいいのかもしれませんが、  
今回、権限毎で処理を変えたいControllerが多数あり、  
if文を量産してしまうことになります。

そのため、  
cancancanやその他gemなどを用いて、  
そこの処理を完結にまとめられないかなと考えております。

cancancanのAbilityクラスなどはまさにそういったことができるのかなと思ったのですが、

あくまで

can  
cannot

の振り分けしかできないのかなというのが私の理解です。

皆さんならこういう用件に対して、どのようにアプローチするのでしょうか？

よろしくお願いします。
CC BY-SA 3.0
2016-05-30T13:30:31.903
25311
2016-05-31T15:07:41.633
13175
question
ruby-on-rails ruby
cancancanで権限毎にControllerのロジックを変えたい(current_userの場合とadminの場合)のですが、if文が多くなり困っております。
[pundit](https://github.com/elabs/pundit) だと明示的に書くことができますね。

下記のようにポリシーファイルを書いて、

```

    class ArticlePolicy < ApplicationPolicy
      class Scope < Scope
        def resolve
          if user.admin?
            scope.all
          else
            user.articles
            # または、 
            # scope.where(user_id: user.id)
          end
        end
      end   
    end
    
```

controller では、次のように使います。

```

    def index
      @articles = policy_scope(Article)
    end
    
```

ポリシーファイルの`scope`には、`Article`が渡ります。

cancancan は詳しくないのですが、`load_resource` が似たような仕組みなのではないでしょうか？

ポリシーファイルで、admin 以外に対する where 条件を付記し、

```

    if user.admin?
      can :index, Article
    else
      can :index, Article, user_id: user.id
    end
    
```

controller で、`load_resouce` を書くと、自動的に @articles に読み込まれる

```

    class ArticlesController < ApplicationController
       load_resource
    
       def index
         @articles # <- 自動的に @articles が定義される。
       end
    
```

のではないかと思います。

<https://github.com/CanCanCommunity/cancancan/wiki/Authorizing-controller-
actions#load_resource>  
<https://github.com/ryanb/cancan/wiki/Fetching-Records>
CC BY-SA 3.0
2016-05-31T15:07:41.633
25345
2016-05-31T15:07:41.633
7471
25311
answer