由于.joins,Rails N + 1?

时间:2016-04-28 09:27:01

标签: sql ruby-on-rails

我在rails应用中搜索了一些帖子。它搜索帖子的标签和帖子的内容(正文)。一切正常,但子弹呻吟有关N + 1查询。

N+1 Query detected Post => [:tags] Add to your finder: :includes => [:tags]

在我的情况下如何避免这种情况?代码看起来像这样:

模型

  def self.search(search)
    Post.joins(:tags).where("name LIKE ? or body LIKE ?", "%#{search}%", "%#{search}%").uniq
  end

控制器

  def index
    if params[:search]
      @posts = Post.includes(:author).search(params[:search])
    else
      @posts = Post.includes(:author, :tags).all
    end
  end

如果我使用.includes而不是.joins,我会得到以下内容:

SQLite3::SQLException: no such column: name:
那么,作为初学者,如何应对呢?有更好的解决方案吗?提前谢谢!

1 个答案:

答案 0 :(得分:2)

您需要在WHERE子句中告诉ActiveRecord您正在使用哪个表。

在大多数情况下,您可以使用这样的哈希来定位关联的表:

Post.includes(:tags).where(tags: { name: 'foo' })

当使用LIKE时,你需要创建一个字符串条件,在这种情况下你只需指定表:

class Post
  # don't use an argument with the same name as the method.
  # its confusing and can lead to strange edge cases.
  def self.search(query)
    # Note that we use a named placeholder instead of ?
    self.includes(:tags)
        .where("tags.name LIKE %:q% OR posts.content LIKE %:q%", q: query)
        .uniq
  end
end