cancancan、とても便利ですね。
しかし、所有者なら変更できるなどの簡単な条件なら日本語のブログなどが多くありますが、複雑な条件を設定する方法について書かれた日本語の記事はあまり多くありません。
もちろん、wikiに記述があるので、英語に抵抗がない方はそちらを読んだほうが良いと思います。
単純な条件
ともあれ、まずは単純な条件での権限の設定の方法を確認しておきましょう。
ブログの著者は、任意の操作が可能。それ以外の人は読み取りのみ可能であるようなブログを考えます。
can :manage, Blog, author: user
can :read
このように、簡単な条件だけであれば、ハッシュで指定することが可能です。
やや複雑な条件
さて、次は少しだけ複雑な条件を考えます。
ユーザーは1つのグループに属しており、著者と同じグループのユーザーは任意の操作が可能であるとしましょう。
この程度であれば、まだハッシュで指定することが可能です。
can :manage, Blog, author: { group: {id: user.group.id } }
また、ハッシュで指定する際、次のようにhoge_idsというメソッドが使用できます
can :manage, Blog, group: { id: user.group_ids }
この場合は、ブログが属するグループにユーザーが属していると、任意の操作が可能になります(ブログとグループは多対一、ユーザーとグループは多対多です)。
もっと複雑な条件
もし、設定したい権限をハッシュで表現できない場合は、ブロックを使用することができます。
公開日時が未来に設定された物以外を読み取り可能にするには、次のように設定することができます。
can :read, Blog { |b| b.published_at <= Time.now }
さらに、スコープを使用することもできます。
can :read, Blog, Blog.where(private: false) { |b| b.published_at <= Time.now }
まとめ
cancancanを使うと、簡単な条件はもちろん、複雑な条件もブロックを使用することで表現できるようになります。
私の拙い英語力では読み取りミスをしている可能性が否定できないので、この記事を読んで概要を把握したら、公式のドキュメントを読みましょう!