从另一个控制器的show动作发布评论

时间:2012-10-19 04:54:04

标签: ruby-on-rails ruby

我有一个典型的博客应用,用户可以在帖子#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,因为评论是通过帖子关联建立的 - 即使评论未通过验证且未得到保存。

你如何解决这个问题?

3 个答案:

答案 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)

在不知道您的postscomments模型是什么样的情况下,有点难以确定问题,但这就是我如何解决您的问题:

# 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部分在语法上是否正确 - 我还没有使用模板引擎。

请注意,这不是生产安全的代码!我已经省略了很多手续,以便保持这个例子的简短和(希望)到位。