require_same_role_as(component_page, *filters)

routes.rb をコンポーネント単位で自由に書き換えられるようにしてしまった関係で、http(s)://{domain}[:{port}]/components/{component_name} を含むURIは任意に扱えることができてしまう。

つまり(Widgetを作る以外は)普通にRailsのApp開発と変わらない状況になったが。


で、Component Page をどうやって始末しようかと考えていて、一つ思ったのは、いくらRESTfulだ、ROAだ、といったとしても、アクセス権限はリソースベースじゃなくて機能ベースに考えた方がわかりやすいのではないかな?、と思ったところで、機能をリソースとして表現するURI、としてComponent Page を定義することにしてみた。

つまり、

/component/system/account/XXXX

で、いままではアカウントの操作をしていたけれども、そうではなくて、

/component/system/account/ => redirect to /components/system/users/{current_user.id}

となって、さらに、

  • /components/system/users/{current_user.id}/general
  • /components/system/users/{current_user.id}/avatar
  • /components/system/users/{current_user.id}/friends
  • ..

などアカウント情報を操作するURIが存在するが、すべて /component/system/account の機能によってリソースの存在が明らかにされるため、これらのURIは、/component/system/account にアクセス可能なユーザーによってのみアクセスされる、というややこしいもの。

機能に対してアクセス可能なロールを設定することができるようになっているのが普通のCMSだけれども、RESTのCRUDの一つ一つに対してロールの設定なんてことをやるサイト管理者なんていないので、サイト管理者が管理しやすい機能単位で/component/system/account というURIを提供してここを(サイト管理者からみた)管理対象としよう、ということです。

で、Railsのコードの中で、

require_same_role_as, "system/account", :only => :avatar
def avatar
end

require_same_role_as, "system/account", :only => :friends
def friends
end

とかけるようにした。requre ... :only => [:avatar, :friends] でもいいんだけれど、どうもフィルタとメソッドが近くにないと不安になってしまう体質なのでこんな書き方。

本当は、

belongs_to_function "system/account", :only => :avatar
def avatar
end

とやって、リソースのURIが、機能のURIに結びつくこと述語的にかけるようにしようか、とも思ったんだけれども、アクセス制御以外にこのような結びつきが必要かどうかが不明。