如果验证失败,则显示注释错误

时间:2016-11-07 09:59:05

标签: ruby-on-rails validation ruby-on-rails-4

我有一个表格,登录用户可以在帖子中添加评论。到目前为止,这是我的文件中的代码:

# views/posts/show.html.haml
%h3 This post has #{ pluralize(@post.comments.count, "comment") }
= render @post.comments # views/comments/_comment.html.haml
= render "comments/form" 

# views/comments/_comment.html.haml - list all comments of the post
.media
  .media-body
    %h4.media-heading
      = comment.user.name
      %small added #{time_ago_in_words comment.created_at} ago
    %p= comment.body
%hr

# views/comments/_form.html.haml
- if user_signed_in?
  = errors_for @comment if @comment # errors_for is just a custom helper I've created to loop through all validation errors

  = form_for([@post, Comment.new]) do |f|
    .form-group
      = f.label :body, "Leave a comment"
      = f.text_area :body, class: "form-control", rows: "6"
    .form-group
      = f.submit "Add", class: "btn btn-primary"

# controllers/comments_controller.rb
def create
    @post = Post.find(params[:post_id])

    @comment = @post.comments.create(params[:comment].permit(:body).merge(:user => current_user))

    if @comment.errors.any?
      render "posts/show"
    else
      redirect_to post_path(@post)
    end

    # have also tried this way too
    # @comment = @post.comments.build(params[:comment].permit(:body))
    # @comment.user = current_user
    # if @comment.save
    #  redirect_to post_path(@post)
    # else
    #  render "posts/show"
    # end
end

当我点击提交按钮添加表单为空的评论(评论正文是必需的)时,我得到这个奇怪的错误(更好的错误宝石)

NoMethodError at /posts/1/comments

undefined method `>' for nil:NilClass

并在%small added #{time_ago_in_words comment.created_at} ago中突出显示这行代码_comment.html.haml。另外,postID和userID按预期分配给@comment,而comment.body和created_at以及updated_at都是nill,如预期的那样。

我已暂时从此文件中删除了所有ruby嵌入代码,一切正常 - 除了我没有得到评论列表这一事实 - 验证按预期工作,我可以在屏幕上看到错误。

我该如何解决这个问题?

修改

工作正常,但是我还在努力再做一件事。如果帖子已经有一些旧评论,我收到N + 1查询正在运行的警告。

N+1 Query detected
  Comment => [:user]
  Add to your finder: :includes => [:user]
N+1 Query method call stack
  /app/views/comments/_comment.html.haml:5:in `_app_views_comments__comment_html_haml__3499194119219243109_33739760'
  /app/views/posts/show.html.haml:23:in `_app_views_posts_show_html_haml__2205508389884571191_36379560'
  /app/controllers/comments_controller.rb:10:in `create'

/app/views/comments/_comment.html.haml:5:in `_app_views_comments__comment_html_haml__3499194119219243109_33739760'
/app/views/posts/show.html.haml:23:in `_app_views_posts_show_html_haml__2205508389884571191_36379560'
/app/controllers/comments_controller.rb:10:in `create'

我知道这不是主题,但任何想法如何解决这个问题?我到底需要使用.includes(:user) ??

1 个答案:

答案 0 :(得分:0)

正如您已经说过“created_at ... is nil”。即使您的代码行被注释掉,它仍然会被erb评估,导致time_ago_in_words抛出零异常。最好使用条件语句,例如:

# views/comments/_comment.html.haml - list all comments of the post
.media
  .media-body
    %h4.media-heading
      = comment.user.name
      - if comment.created_at.present?
        %small added {time_ago_in_words comment.created_at} ago
      - else
        % small comment not yet been created
    %p= comment.body
%hr