【问题标题】:N+1 queries when submiting validations errors occur提交验证错误时发生 N+1 个查询
【发布时间】:2016-11-07 20:31:17
【问题描述】:

我有一个表单,登录用户可以在其中将 cmets 添加到帖子中。表格发到comments_controller:

# 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

# 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
- if comment && comment.created_at.present?
  .media
    .media-body
      %h4.media-heading
        = comment.user.name
        %small added #{time_ago_in_words comment.created_at} ago
      %p= comment.body
  %hr

comment.body 作为必填字段。

如果我尝试向没有 cmets 的帖子提交一个空表单,这可以正常工作,"posts/show" 视图会按预期呈现验证错误。现在,如果我在已经包含一些 cmets 的帖子中再次重复相同的步骤,我会收到 N+1 查询正在运行的警告。这是来自Bullet gem:

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'

我该如何解决这个问题?

【问题讨论】:

  • 你的_comment.html.haml部分有什么?
  • 我做了更新
  • 我明白了,所以,您需要加载您的 commentscommens' users 以避免该错误。试试Post.includes(comments: :user).find(params[:post_id])
  • 是的,就是这样!我一直在苦苦挣扎,并试图在包含 @post.comments.create 的行中添加 .includes(:user).includes(comments: :user),正如 Bullet 所说的 /app/controllers/comments_controller.rb:10:in create'`,但没有成功。
  • 无论如何感谢您的帮助!你想把它写成答案,以便我将其标记为正确吗?

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


【解决方案1】:

你需要告诉 Rails 像这样加载 postcommentscomments' user

Post.includes(comments: :user).find(params[:post_id])

【讨论】:

    猜你喜欢
    • 2023-04-03
    • 2020-03-04
    • 2015-12-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多