‘includes’方法似乎不适用于Rails 4中的’where’

在我的模型中我有:

class Song < ActiveRecord::Base belongs_to :artist def self.default_scope includes :artist end def self.search query if query where "title LIKE :query OR artists.name LIKE :query", query: "%#{ query }%" else where nil end end end 

在我的控制器中:

 def index @songs = Song.search(params[:search]) respond_with(@songs) end 

当我搜索时,我收到以下错误:

 Mysql2::Error: Unknown column 'artists.name' in 'where clause': SELECT `songs`.* FROM `songs` WHERE (title LIKE '%my search%' OR artists.name LIKE '%my search%' OR albums.name LIKE '%my search%') 

我做错了什么?,我认为include方法会自动进行连接。

来自文档 :

使用这样的where只有在你传递哈希时才有效。 对于SQL片段,您需要使用references来强制连接表

你是正确的, includes方法将自动进行连接,但只有当哈希被用作where的参数时。

这将检测查询并加入comments

 Article.includes(:comments).where(comments: { visible: true }) 

这需要一个明确的references

 Article.includes(:comments).where("comments.visible = true").references(:comments) 

在不了解default_scope是否是好事的情况下,您可以使用以下代码运行代码:

 def self.search(query) if query references(:artists). where("title LIKE :query OR artists.name LIKE :query", query: "%#{query}%") else where nil end end 

includes不生成join sql,因此您无法访问其他表列。 事实上,这是一个非常棘手的方法,通常最好使用preloadjoins – 理解差异将对您的应用程序性能产生巨大影响。 你需要在这里使用join

 class Song < ActiveRecord::Base belongs_to :artist default_scope { joins :artist } def self.search query if query where "title LIKE :query OR artists.name LIKE :query", query: "%#{ query }%" else all end end end 

但是请注意,使用default_scope进行连接或包含并不是最干净的方式,并且最终会对你产生负面影响(从困难的角度来看)会带来性能损失。