2012-04-01 16 views
1

私は自己結合モデルを定義しました。基本的にはフォーラムの投稿、それが属するparent_postです。自己結合ActiveRecord、Parent_Post_IDと私

class Post < ActiveRecord::Base 
    has_many :replies, :class_name => "Post" 
    belongs_to :thread, :class_name => "Post", :foreign_key => "parent_post_id" 
end 

これは基本的には思われます。私は、返信アクションとアクションとビューのための新しいRESTfulルートを作成しました。

ルート:

resources :forums do 
    resources :posts do 
     member do 
     get 'reply' 
     end 
    end 
    end 

ビュー層とコントロールアクション私はまずいなってるところのようです。

def reply 
    @forum = Forum.find(params[:forum_id]) 
    @post = @forum.posts.build 
    @post.thread = @forum.posts.find(params[:id]) 
    @post.title = "RE: #{@post.thread.title}" 
end 

def create 
    @forum = Forum.find(params[:forum_id]) 
    @post = @forum.posts.build(params[:post]) 
    @post.user = current_user 
    if @post.save 
    redirect_to forum_post_path(@forum, @post), notice: 'Post was successfully created.' 
    else 
    render action: "new" 
    end 
end 

そして、ビューレイヤーでは、標準の新しい編集アクションに使用しているのと同じスキャフォールド生成フォーム部分を使用しようとしていました。

#reply.html.erb 
<%= render :partial => 'form' %> 

#_form.html.erb 
<%= form_for [@forum,@post], :html => { :class => 'form-horizontal' } do |f| %> 
    <fieldset> 
    <legend><h1>New Thread</h1></legend> 

    <div class="control-group"> 
     <%= f.label :title, :class => 'control-label' %> 
     <div class="controls"> 
     <%= f.text_field :title, :class => 'text_field span9' %> 
     </div> 
    </div> 
     <div class="control-group"> 
     <%= f.label :body, :class => 'control-label' %> 
     <div class="controls"> 
     <%= f.text_area :body, :class => 'text_area span9' %> 
     </div> 
    </div> 
    <div class="form-actions"> 
     <%= f.submit 'Submit', :class => 'btn btn-primary' %> 
     <%= link_to 'Cancel', forum_posts_path(@forum), :class => 'btn' %> 
    </div> 
    </fieldset> 
<% end %> 

ただし、投稿を作成するときにparent_post_idが失われていて、それがnilに設定されています。別のアクションを作成する必要がありますか?スレッドを設定する他の方法はありますか?三番目のこと?

答えて

0

はこれが動作するフォームに

<%= hidden_field_tag :forum_id , @forum.id %> 

を追加します。

返信アクション:

@forum = Forum.find(params[:forum_id]) 
@post = @forum.posts.build 
@post.thread = @forum.posts.find(params[:id]) 
@post.title = "RE: #{@post.thread.title}" 

そして、これを追加するビューに

<%= f.hidden_field :parent_post_id, @post.thread.id %> 

私は組み込みのRESTfulメソッドを使用するのではなく、カスタムreplyメソッドが必要かどうか質問しますが、これは問題を解決するはずであり、それは本当にあなたの質問ではありません。

+0

私は新しいスレッドの作成と応答の区別を区別していましたが、誤っている可能性があります。このロジックを新しいものに追加して1日と呼びますか? – DVG

+1

唯一の違いは、1つ(返信投稿)にparent_idがあり、もう1つ(新しい投稿)には表示されないということです。どちらも新しい投稿を作成するだけです。違いがさらに複雑になった場合は、スレッドコントローラを持つことを検討することができます。私の主な提案は、RESTfulルートにカスタムメソッドを追加する必要性について疑問を呈することでした。あなたがそれをやっていると分かったら、別のコントローラーの必要性を考慮する必要があります。 –

+0

うわー、 'スレッド'コントローラのアイデアは、実際には全く反対のアイデアを考えさせました。なぜ、「返信」コントローラではないのですか?私は思っていることを投稿します。 – Azolo

0

基本的には、Posts#createアクションを送信するときに、/forum/1/postsのようなURLを送信すると、URLからparent_post_idが削除されます。あなたはそのURLを構築するためにそのparent_post_idを使用しているので、POSTへの道が必要です。

postsリソースにネストされているリソースにPOSTからreplyリソースを許可しています。
(すなわちPOST /forums/1/posts/1/reply

そのため、おそらくこの

resources :forums do 
    resources :posts do 
    # :show is actually just pointing to a form 
    resource :reply, :only => [:show, :create], 
        :controller => 'reply' #otherwise gets routed to 'replies' 
    end 
end 

のようなものは、だから、またReplyControllerが必要になるが、それは基本的にいくつかの変更であなたのポストのコントローラ上のごreply方法と一致します。

def show 
    @forum = Forum.find(params[:forum_id]) 
    @post = @forum.posts.find(params[:post_id]) 
    @reply = @forum.posts.build 
    @reply.thread = @post 
    @reply.title = "RE: #{@post.thread.title}" 
end 

def create 
    @forum = Forum.find(params[:forum_id]) 
    @post = @forum.posts.find(params[:post_id]) 
    @reply = @forum.posts.build(params[:reply]) 
    @reply.thread = @post 
    @reply.user = current_user 
    if @reply.save 
    redirect_to forum_post_path(@forum, @post), notice: 'Reply was successfully created.' 
    else 
    render action: "show" 
    end 
end 

最大の問題は、あなたのform forブロックから抽象ごPostフィールドに持っているということだろう。これは、POSTにしようとしているURLが異なるためです。

返信/ show.html.erb

<%= 
    form_for @reply, :url => forum_post_reply_path(@forum, @post), 
        :html => { :class => 'form-horizontal' } do |builder| 
%> 
    <fieldset> 
    <legend><h1>New Reply</h1></legend> 

    <%= render "posts/post_fields", :f => builder %> 

    <div class="form-actions"> 
     <%= builder.submit 'Submit', :class => 'btn btn-primary' %> 
     <%= link_to 'Cancel', forum_post_path([@forum, @post]), :class => 'btn' %> 
    </div> 
    </fieldset> 

<% end %> 

ポスト/ _form.html.erb

<%= form_for [@forum,@post], :html => { :class => 'form-horizontal' } do |builder| %> 
    <fieldset> 
    <legend><h1>New Thread</h1></legend> 

    <%= render "post_fields", :f => builder %> 

    <div class="form-actions"> 
     <%= builder.submit 'Submit', :class => 'btn btn-primary' %> 
     <%= link_to 'Cancel', forum_posts_path(@forum), :class => 'btn' %> 
    </div> 
    </fieldset> 
<% end %> 

:しかし、それはちょうどこのような何かをやってあまりにも悪いことではないはずです投稿/ _post_fields.html.erb

注:おそらく私が持っているよりもルートを宣言するためのより良い方法がありますが、私は実際にはわかりません。