Самостоятельно присоединяюсь к ActiveRecord, Parent_Post_ID и мне - PullRequest
1 голос
/ 02 апреля 2012

Итак, я определил модель самообъединения В основном пост на форуме и parent_post, к которому он принадлежит.

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

И в слое вида я просто пытался использовать ту же часть, сгенерированную скаффолдом, которую я использую для стандартных действий new и edit.

#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. Нужно ли создавать еще одно действие? Есть ли другой способ установить поток? Какая-то третья вещь?

Ответы [ 3 ]

0 голосов
/ 02 апреля 2012

Это будет работать:

Ответное действие:

@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 %>

Кстати, я спрашиваю, нужен ли вам собственный метод reply, в отличие от использования встроенных методов RESTful, но это должно решить вашу проблему, а на самом деле это был не ваш вопрос.

0 голосов
/ 02 апреля 2012

Таким образом, в основном, когда вы отправляете действие Posts#create, вы отправляете URL-адрес, похожий на этот /forum/1/posts, который удаляет parent_post_id из URL-адреса.Поскольку вы используете этот parent_post_id для создания этого URL, вам нужен способ POST с ним.

Я предлагаю разрешить POST ресурсу reply, который вложен в ресурс posts.
(то есть 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

Самая большая проблема будетбудь то, что вы должны абстрагировать свои Post поля от вашего form for блока.Это потому, что URL-адрес, по которому вы пытаетесь POST, будет другим.Но это не должно быть слишком плохо, просто делая что-то вроде этого:

reply / 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 %>

posts / _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 %>

posts / _post_fields.html.erb

<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>

Примечание. Вероятно, существует более удобный способ объявления маршрутовчем я, но я действительно не знаю.

0 голосов
/ 02 апреля 2012

добавьте

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

к вашей форме

...