我正在进行在线教程,其任务是实现嵌套在帖子资源下的评论资源,后者又在主题资源下。我已经找到了练习的所有步骤,只是将“评论创建”表单显示在帖子#show上。我已经尝试了几个小时来修复它,但一直收到以下错误:undefined method "model_name" for NilClass:Class
。我不知道model_name
是指什么,在我的绝望中,我甚至在GitHub上查看了教程的代码,但我仍然无法看到我犯错误的地方。
我的表单是部分的,错误指向第一行,所以我先将这段代码粘贴到此处:
<%= form_for [topic, post, comment] do |f| %>
<div class="controls">
<%= f.text_area :body, rows: 8 %>
</div>
<div class="control-group">
<div class="controls">
<%= f.submit "Add Comment", class: 'btn' %>
</div>
</div>
<% end %>
我会发布我的路线,以便您可以看到嵌套:
X::Application.routes.draw do
devise_for :users
resources :topics do
resources :posts, except: [:index] do
resources :comments, only: [:create]
end
end
match "about" => 'welcome#about', via: :get
root to: 'welcome#index'
end
这是我的评论控制器:
class CommentsController < ApplicationController
def new
end
def create
@topic = Topic.find(params[:topic_id])
@post = Post.find(params[:post_id])
@comment = current_user.comments.build(params[:comment])
@comment.post = @post
if @comment.save
flash[:notice] = "Comment was saved."
redirect_to @post
else
flash[:error] = "Error! Try again."
render :new
end
end
end
这是我的帖子#show view(表格应该在底部呈现):
<h1><%= markdown @post.title %></h1>
<div class="row">
<div class="span8">
<small>
<%= image_tag(@post.user.avatar.tiny.url) if @post.user.avatar? %>
submitted <%= time_ago_in_words(@post.created_at) %> ago by
<%= @post.user.name %>
</small>
<br><br>
<p><%= image_tag(@post.image.url) if @post.image? %></p>
<p><%= markdown @post.body %></p>
</div>
<div class="span2">
<% if can? :edit, @post %>
<%= link_to "Edit Post", edit_topic_post_path(@topic,@post), class: 'btn btn-small' %>
<% end %>
</div>
</div>
<br><br>
<h4>Comments</h4>
<%= render @comments %>
<br>
<%= render :template => "/comments/_form.html.erb", locals: { topic: @topic, post: @post, comment: @comment } %>
如果有人能帮我解决这个问题,我将非常感激。如果有任何我应该添加的信息,请告诉我。谢谢!
答案 0 :(得分:0)
一般来说,我读过它不推荐使用3级嵌套资源。你能链接到你正在关注的教程吗?
无论如何我建议在你的路线上使用浅。
resources :topics, shallow: true do
resources :posts, except: [:index], shallow: true do
resources :comments, only: [:create]
end
end
将为您提供以下资源,这些资源可以让您更轻松地在视图中创建正确的表单。
post_comments POST /posts/:post_id/comments(.:format) comments#create
topic_posts POST /topics/:topic_id/posts(.:format) posts#create
new_topic_post GET /topics/:topic_id/posts/new(.:format) posts#new
edit_post GET /posts/:id/edit(.:format) posts#edit
post GET /posts/:id(.:format) posts#show
PATCH /posts/:id(.:format) posts#update
PUT /posts/:id(.:format) posts#update
DELETE /posts/:id(.:format) posts#destroy
topics GET /topics(.:format) topics#index
POST /topics(.:format) topics#create
new_topic GET /topics/new(.:format) topics#new
edit_topic GET /topics/:id/edit(.:format) topics#edit
topic GET /topics/:id(.:format) topics#show
PATCH /topics/:id(.:format) topics#update
PUT /topics/:id(.:format) topics#update
DELETE /topics/:id(.:format) topics#destroy
现在您只需将post_id发送到您的评论表单即可。阅读更多here我在3级嵌套方面没有多少工作,但这可以让你了解如何让自己更容易。
修改强> 在create操作中,您应该使用@post构建注释,然后将用户设置为current_user。
def create
@post = Post.find(params[:post_id])
@comment = @post.comments.build(params[:comment])
@comment.user = current_user
if @comment.save
flash[:notice] = "Comment was saved."
redirect_to @post
else
flash[:error] = "Error! Try again."
render :new
end
end
现在不需要@topic
<%= render :template => "/comments/_form.html.erb", locals: { post: @post, comment: @comment } %>
答案 1 :(得分:0)
将'@comment = Comment.new'添加到PostController的“show”动作中。它只在CommentController“创建”操作中定义。