ちょうどタイミング良く@maihaさんから、@yuguiさんが
近くに来てるという情報をもらったので、
@yamazさんも交えて、ネストしたリソースを扱うコントローラの問題の答えを得るべく、ミーティングをしました。

問題の定義:

モデル層で Post has_many Comment な関係にある時に、
Commentのリストとコメント投稿フォームを含むPosts#show画面(典型的な例としてはブログの一記事表示画面)から、Commentを投稿した場合に、

  1. Comments#createで受け取ると、Commentのsaveに失敗した時に、Post#showを表示したいが、redirect resource(@comment.post) すると、@comment.errorsの情報がロストしてしまう。
  2. Posts#create_commentなどで受け取ると、Commentリソースの処理をPostsコントローラで行う事になって責任の範囲が不明確になり、格好が悪い。

解決策

Merbベースでコンセプトを示します。
まずは、Postsコントローラの中で、以下のような包含関係を宣言するようにします。

ruby>>
class Posts < Application
has_many :comments
end

class Admin < Application
has_many :comments
end
<<--

これにより、コントローラ同士の協調関係を、コントローラ自身が知っているという事になります。
具体的にhas_manyがやることは、以下のようなbeforeフィルターをshowアクションに対してセットする事です。

ruby>>
class Posts < Application
before :only => :show do
controller = Comment.new(request)
@comment = case request.method
when "POST"; controller._dispatch(:create)
when "PUT"; controller._dispatch(:update)
when "DELETE"; controller._dispatch(:destroy)
end
end
<<--

:showアクションに対して、本来は使われない"POST", "PUT", "DELETE"
の各メソッドでのリクエストがあった場合に、Commentsコントローラに処理を回します。"GET"の場合は普通にPosts#showが行われます。
Commentsコントローラ側では、メソッドの返り値としてcommentオブジェクトを返します。

ruby>>
def create(comment)
Comment.create(comment)
end
<<--

作成に失敗した場合は、@comment.errorsにエラー情報が入っているので、
Posts#showの中から利用出来ます。

Posts#show内のComment投稿フォームは以下のような感じで、
Post#showに対してサブミットします。

html>>
<%= form_for @comment, :action => resource(@post) do %>
<%= partial "comments/form" %>
<% end =%>
<<--

コンセプトなので実際に動くかどうかまだ検証してないですが、
こんな感じで良いのではないかと。

MerbだとControllerがresponseの生成を担当していないので、
コントローラをまたいだ処理のネストが高速に行えます。
Railsの場合は、個々のアクションの実行がresponseの生成を伴うので、
この方法だとオーバヘッドが大きくて難しいかもしれません。

posted by genki genki on Tue 20 Jan 2009 at 02:03 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小説リーダー
小説投稿サイトの公式ページを開き、WebView表示と読み上げ向け表示を切り替えて、移動中や作業中にもWeb小説の続きを聴きやすくするiPhoneアプリです。
補助探
公開されている補助金・助成金情報を集約し、条件に合う制度を探しやすくするサービスです。
jotter.me
個人開発者のためのホスティング一体型ノートサービス
ハンドミラー
iPhone向けの手鏡アプリ
ツイプロ(twpro)
Twitterプロフィールの高速検索エンジン