看看我刚才问的这个问题:对多种型号的评论
到目前为止,我已经正确设置了所有内容,我的评论表,我的模型和控制器。
但是,我遇到了一些路线错误。
在我的路线文件中:
resources :posts do
resources :comments do
member do
put "like", to: "comments#upvote"
end
end
end
resources :books do
resources :comments do
member do
put "like", to: "comments#upvote"
end
end
end
我的意见表:
<% form_for [@commentable, Comment.new] do |f| %>
<p>
<%= f.text_area :body %>
</p>
<p><%= f.submit "Submit" %></p>
<% end %>
这是我得到的错误:
未定义的方法`comments_path'
你知道如何让路线正常运行吗?
编辑:
这就是我在评论控制器中的内容:
def index
@commentable = find_commentable
@comments = @commentable.comments
end
def create
@commentable = find_commentable
@comment = @commentable.comments.build(params[:comment])
if @comment.save
flash[:notice] = "Successfully created comment."
redirect_to :id => nil
else
render :action => 'new'
end
end
private
def find_commentable
params.each do |name, value|
if name =~ /(.+)_id$/
return $1.classify.constantize.find(value)
end
end
nil
end
@Katie,在呈现评论表单的每个操作中都应该加载@commentable
。我认为您放弃了comments#new
,而是使用books#show
或posts#show
来呈现表单(这很好),但每次想要呈现表单时都需要加载该变量。
然而,由于在books#show
中定义@commentable
变量不是很有表达性(您可能已经定义了@book
),因此我建议:
为评论表单创建一个新的部分(如果你还没有):
<% form_for [commentable, Comment.new] do |f| %>
<p>
<%= f.text_area :body %>
</p>
<p><%= f.submit "Submit" %></p>
<% end %>
请注意,这里commentable
不是实例变量。渲染分部时,将其定义为局部变量。books/show.html.erb
中的某个位置:
<%= render partial: "comments/form", locals: { commentable: @book } %>
显然,在其他视图中,用应该是commentable
的任何变量替换@book
。
现在您将遇到另一个问题,即表单数据不会携带commentable_type
和commentable_id
属性。有很多方法可以让它们进入您的CommentsController
;这里有一个使用隐藏字段的简单例子:
<% form_for [commentable, Comment.new] do |f| %>
<%= hidden_field_tag :commentable_type, commentable.class.to_s %>
<%= hidden_field_tag :commentable_id, commentable.id %>
<p>
<%= f.text_area :body %>
</p>
<p><%= f.submit "Submit" %></p>
<% end %>
您需要将find_commentable
操作更改为更简单的操作:
def find_commentable
params[:commentable_type].constantize.find(params[:commentable_id])
end
如果在PostsController#show
操作下呈现注释表单,则需要确保在该操作中的某个位置定义了@commentable
。
# PostsController#show
def show
@post = Post.find(params[:id])
@commentable = @post
end
这样,就定义了在form_for [@commentable, Comment.new]
调用中使用@commentable
。