我在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:
那么,作为初学者,如何应对呢?有更好的解决方案吗?提前谢谢!
答案 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