在我的模型中我有:
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方法会自动进行连接。
答案 0 :(得分:6)
来自docs:
像这样使用
where
只有在你传递哈希时才有效。对于 您需要使用references
来强制连接表的SQL片段
你是正确的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
答案 1 :(得分:2)
includes
不会生成join
sql,因此您无法访问其他表列。事实上,这是一个非常棘手的方法,通常最好使用preload
或joins
- 了解差异会对您的应用程序性能产生巨大影响。您需要在此处使用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进行连接或包含并不是最干净的方式,最终会对你产生负面影响(从困难的角度来看)会受到性能损失。