所以我定义了一个自连模型。基本上是论坛上的帖子,以及它所属的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
在视图层中,我只是尝试使用相同的脚手架生成的部分我正在使用标准的新编辑操作。
#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 :(得分:0)
添加
<%= hidden_field_tag :forum_id , @forum.id %>
到您的表单
答案 1 :(得分:0)
这将有效:
回复行动:
@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 %>
BTW我怀疑你是否需要一个自定义的reply
方法,而不是使用内置的RESTful方法,但这应该可以解决你的问题,这不是你的问题。
答案 2 :(得分:0)
基本上,当您提交Posts#create
操作时,您提交的网址类似于此/forum/1/posts
,会从网址中删除parent_post_id
。由于您使用parent_post_id
来构建该网址,因此您需要使用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
字段。那是因为你试图POST
的网址会有所不同。但是做这样的事情应该不会太糟糕:
回复/ 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 强>
<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>
注意:可能有更好的方式来声明路线,但我真的不知道。