ちょうどタイミング良く@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コントローラの中で、以下のような包含関係を宣言するようにします。

   1  class Posts < Application
   2    has_many :comments
   3  end
   4  
   5  class Admin < Application
   6    has_many :comments
   7  end

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

   1  class Posts < Application
   2    before :only => :show do
   3      controller = Comment.new(request)
   4      @comment = case request.method
   5      when "POST"; controller._dispatch(:create)
   6      when "PUT"; controller._dispatch(:update)
   7      when "DELETE"; controller._dispatch(:destroy)
   8      end
   9    end

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

   1  def create(comment)
   2    Comment.create(comment)
   3  end

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

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

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

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

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

posted by Png genki on Tue 20 Jan 2009 at 02:02
Contents
ネストしたリソースの問題の解決策を考えてみた
Comments
dsjf: https://gist.github.com/6bf1bf2c3cbb5eb6e7a7 これ... '13-1
瀧内元気: おお、チェックしてみます。thx! '11-12
overisland: Reeder for iPhone もこの UI を実装していますね。 '11-12
瀧内元気: その情報は見たのですが、以下のサイトによると、現在はまた必要になってるっぽいんですよね。 ... '11-12
tkawa: http://devcenter.heroku.com/articles/rails31_he... '11-12
Services from s21g
twpro(ツイプロ)
Twitterプロフィールを快適検索
地価2009
土地の値段を調べてみよう
MyRestaurant
自分だけのレストラン手帳
Formula
ブログに数式を埋め込める数式コミュニティ