権限管理を実装するときの地味な話

「あるユーザがXをYできるかどうか」というメソッドを定義したいとき、Userに実装するよりも、Xに実装した方がうまくいくことが多かった。例えば「ユーザが投稿を編集できるか」という、ブログの共同編集のような機能で使うやつで考える。つまり、User#can_edit?(entry) みたいなやつにするか Entry#editable_by?(user) みたいなやつにするかという話になる。

後者の方でうまくいった理由は、Webアプリだとログイン中のユーザが存在しない場合というのがあるが、後者ではuserがnilの場合でも対応できたというのと、Userクラスが長大にならなかったという点 (Abilityクラスとかを全ての場所で統一して使えている場合はそれで良いので各自適当にやっていってほしい)。あとメソッドの命名規則の問題があって、名詞形 (例:User#name) か、xxx?で終わるメソッド名のときは subject is xxx または subject has xxx と書けるやつ (例:User#admin?, User#has_any_entry?) か、動詞形 (例:User#create_entry) というパターンしか許していないのだけど、can_xxx? みたいなパターンは許可しにくい。able_to_xxx? か has_grant_to_xxx? だとこのパターンに収められるが、何かおかしい気がするので、entry is editable by user みたいに書ける方が良かったというのもある。User#can_create?(:entry) のように、Entryの実体がまだ存在しない場合もあるのでその場合はUserクラスに実装するしかないが、大抵は何らかの母体 (Blogクラスとか) が存在していることも多いので、そこに生やすのも手。