我有一个典型的博客应用,用户可以在帖子#show模板中发表评论。
resources :posts do
resources :comments
end
# posts_controller.rb
def show
@post = Post.find(params[:id])
@comment = @post.comments.build
end
# comments_controller.rb
def create
@post = Post.find(params[:post_id])
@comment = @post.comments.build(params[:comment])
@comment.author = current_user
if @comment.save
redirect_to @post
else
render 'posts/show'
end
end
在视图中,我首先检查是否有评论,输出它们,然后我显示一个新的评论表单。
/ posts/show.html.slim
- if @post.comments.any?
@post.comments.each do |comment|
p = comment.author.name
...
= form_for [@post, @comment]
如果评论验证失败,我会得到一个'没有nil类的方法名'错误。我认为这是因为@post.commets.any?
返回true,因为评论是通过帖子关联建立的 - 即使评论未通过验证且未得到保存。
你如何解决这个问题?
答案 0 :(得分:3)
当评论验证失败时,可能没有设置comment.author,因此将为nil。这解释了nil.name错误。
您可以尝试类似
的内容@post.comments.each do |comment|
p = comment.author.try(:name)
OR
@post.comments.each do |comment|
unless comment.new_record?
p = comment.author.try(:name)
end
end
OR
@post.comments.reject{|c| c.new_record?}.each do |comment|
p = comment.author.try(:name)
end
答案 1 :(得分:1)
更改
if @post.comments.any?
要
if @post.comments.blank?
再次检查。
答案 2 :(得分:0)
在不知道您的posts
和comments
模型是什么样的情况下,有点难以确定问题,但这就是我如何解决您的问题:
# app/models/post.rb
has_many :comments
# app/models/comment.rb
belongs_to :post
# app/controllers/posts_controller.rb
def show
@post = Post.find params[:id]
end
# app/controllers/comments_controller.rb
def create
# No need to instantiate the post and build the comment on it here since
# we're going to set the post_id on the comment form.
@comment = Comment.new params[:comment]
if @comment.save
# ...
else
# ...
end
end
# app/views/posts/show.html.slim
- if @post.comments.any?
@post.comments.each do |comment|
# ...
- form_for Comment.new do |f|
= f.text_field :author
= f.text_field :body
# ...
= f.hidden_field :post_id, @post.id # This passes the comment's related post_id on to the controller.
= f.submit
我不知道Slim部分在语法上是否正确 - 我还没有使用模板引擎。
请注意,这不是生产安全的代码!我已经省略了很多手续,以便保持这个例子的简短和(希望)到位。