まずはネストという言葉に関する定義の問題ですが、
諸橋さんが書いているように
、PostsコントローラはComments
コントローラを集約(aggregates)しますが、
内包(compose)する訳ではありません。

たとえば、管理画面に対応するAdminコントローラから、
Commentの削除や修正を行う場合に、AdminコントローラからCommentsコントローラを集約する事を考えると、その必要性が分かりやすいと思います。

PostsコントローラにCommentsを制御するコードを書いてしまう(内包してしまう)と、
Adminコントローラで同じ事をする必要が出来た場合に、
同じようなコードを書く必要が出てきます。

Don't Repeat Yourself!

結果として、メンテナンス性の悪いコードが出来上がります。
この事が、Postsコントローラの中でCommentsリソースを制御する
コードを書く事の問題の本質だと思います。
もちろん、あらかじめCommentsを集約する存在が
Postsしか無いと分かっている場合には問題ありません。

という事で、
続いて検索やCRUD以外の操作はどうするのかという問題について。

この問題を考えるための重要な視点として、最近のRailsやMerbでは、
リソースを制御するためのリソースコントローラと、
それ以外の制御をするための汎用コントローラの役割が分けて考えられるようになってきているという事があります。

上述の話の中で登場するコントローラを当てはめてみると、
以下のようになります。

|caption=コントローラの分類
|
|リソースコントローラ,汎用コントローラ
|
|Posts,Admin
|Comments,Dashboard

リソースコントローラとは、特定のモデルに対してCRUD(create, read, update, delete)操作を行う事に特化したコントローラです。

そう考えると、検索やCRUD以外の操作は、
汎用コントローラが行うのが自然な気がします。
例えば、ブログの記事(Posts)やコメント(Comments)
の検索を行う場合であれば、
SearchコントローラがPostsコントローラやCommentsコントローラ
を集約すればOK.
疑似コード的に表現すると、以下のような感じになります。

pre>>
Search#posts with_scope(query){ Posts#index }
Search#comments with_scope(query){ Comments#index }
<<--

この構造は2年ぐらい前にRailsで使ってみたのですが、
Railsのコントローラの実装がネストに向いていないので、
パフォーマンス上の問題に苦しみました。
Railsのコントローラは、フィルタの実行、アクションの実行だけでなく、レスポンスの作成を担っているので、ネストさせた場合に、
いったん作成したレスポンスを破棄する必要があるなど、無駄が大きいのです(Railsではお馴染みのDoubleRenderErrorが発生するのもこのせいです)

しかし今であれば、Merbを使う事によってこの問題は解決します。
Merbのコントローラはレスポンスの作成をする必要が無く、非常にシンプルなので、ネストさせてもパフォーマンスの問題はほとんどありません。

ということで、Merbを使えばみんなHappyになるよという話でした。

前回の記事の追補

前回の記事では、Aggregatorの#showで、POST, PUT, DELETEを
Aggregatedに委譲するという話を書きましたが、
例えばPostsコントローラがCommentsとTrackbacksの
2つのリソースを集約している場合に、
どちらのリソースに対する操作なのかを判別する方法を用意する必要があるので、どうやって実現するか書いておきます。

pre>>
posts/1 -> Posts#show
posts/1/comments -> Posts#show -> Comments
posts/1/trackbacks -> Posts#show -> Trackbacks
<<--

こんな感じに、posts/1/:resource に対するPOST, PUT, DELETEを、
:resourceに対応するリソースコントローラに委譲する感じですね。

posted by genki genki on Wed 21 Jan 2009 at 09:02 with 0 comments
Contents rssrss
光ファイバーを二次元振動させて走査するAR用ディスプレイ
因果の取り違え
Swift2's defer for CoffeeScript
mongodb-3.0からcreateIndexのdropDupsが無くなったらしい
mongodb-3.0以降のWiredTigerの設定を動的に変更する方法
一般楕円の高速生成アルゴリズムへの道標
farro mantecatoのレシピ
Droonga関連の記事のまとめ
RuntimeErrorの特定のメッセージに限定してrescueする方法
jQueryでscriptタグを実行せずにappendする
Tags
coffeescriptdefergroongajsmemonodenodejs
Comments rssrss
瀧内元気 瀧内元気: MacOS版は以下にあります genki/ViMouse 01/16 05:40
dsjf dsjf: https://gist.github.com/6bf1bf2c3cbb5eb6e7a7 これでも出... 01/08 23:23
瀧内元気 瀧内元気: おお、チェックしてみます。thx! 12/24 05:23
overisland overisland: Reeder for iPhone もこの UI を実装していますね。 12/24 05:13
瀧内元気 瀧内元気: その情報は見たのですが、以下のサイトによると、現在はまた必要になってるっぽいんですよね。 http:... 12/01 12:20
tkawa tkawa: http://devcenter.heroku.com/articles/rails31_herok... 12/01 10:47
瀧内元気 瀧内元気: どもー。いまはgithubに置いてあります https://github.com/genki/irb... 07/10 08:31
ともち ともち: こんにちは! すばらしいプログラムをありがとうございます。しかし、merbiのドメイン、切れているみ... 07/10 02:30
Services from s21g
YOMU Web小説リーダー
Web小説を音声で楽しむ読み上げリーダー
補助探
公開されている補助金・助成金情報を集約し、条件に合う制度を探しやすくするサービスです。
jotter.me
個人開発者のためのホスティング一体型ノートサービス
ハンドミラー
iPhone向けの手鏡アプリ
ツイプロ(twpro)
Twitterプロフィールの高速検索エンジン