我似乎无法通过这个思考。如何使用与外卡的belongs_to
关系运行where子句?
require 'pry'
require 'active_record'
require 'sqlite3'
connection = ActiveRecord::Base.establish_connection(
adapter: 'sqlite3',
database: ":memory:",
verbosity: 'quiet'
)
class CreateOwners < ActiveRecord::Migration
def change
create_table(:owners) do |t|
t.string :name
t.date :birthday
end
end
end
class CreateDogs < ActiveRecord::Migration
def change
create_table(:dogs) do |t|
t.string :name
t.belongs_to :owner
end
end
end
CreateOwners.new.migrate(:up)
CreateDogs.new.migrate(:up)
class Dog < ActiveRecord::Base
belongs_to :owner
end
class Owner < ActiveRecord::Base
has_many :dogs
end
这会引发错误
ar = Dog.includes(:owner).where("owners.birthday < ?", Date.today)
ar.inspect #=>SQLException: no such column: owners.birthday
但是在包含之前加入似乎有用吗?
ar = Dog.joins(:owner).includes(:owner).where("owners.birthday < ?", Date.today)
ar.inspect #=> [] (which is correct)
答案 0 :(得分:0)
试试这个。我认为这在你的位置上是一个简单的错字。
ar = Dog.includes(:owner).where("owner.birthday < ?", Date.today)
答案 1 :(得分:0)
所以我最终偶然发现了我的答案。这是includes
通过委派给preload
或eager_load
而在幕后工作的方式。关于它,这是一个很好的blog post。包含未检测到包含模型上调用的where
子句,因此未加入查询中的表 - 它调用preload
而不是eager_load
来激活一个查询,并且与joins(:owner).includes(:owner)
我不知道这是AR中的错误还是我对AR的浅薄理解。
所以我的查询应该是:
Dog.eager_load(:owner).where("owner.birthday < ?", Date.today)
修改强>
所以我离开了一点。 eager_load
调用左外连接,这不是我想要的 - 但是由于where子句我很幸运。如果你想强制一个内连接,那么连接和包含实际上是正确的方法,虽然由于某种原因仍然感觉很奇怪。
这是另一个有助于澄清的resource。