我们已经离开了一个表,以便我们可以按列排序,如果存在关系:
people = Person .joins("LEFT JOIN addresses ON addresses.id = people.address_id") .order("addresses.country") .all
这导致单个SQL查询,但我想让people.first.address不触发sql来加载地址.我是离开加入的,因为有些人没有地址.
.includes(:address)触发单独的查询.
您可以使用包含内部联接的建议,但这会触发2个SQL查询:
Person.includes(:address).all
虽然联接包含触发器只有一个(但INNER联接):
Person.joins(:address).includes(:address).all
如果在急切加载时强制加入,则活动记录也会使用左联接
.eager_load(:地址).
您是否可以使用现有的左连接并使用这些结果加载轨道?到目前为止我找不到这个.
解决方法
试试这个:
people = Person. eager_load(:address). merge(Address.order("coalesce(country,'')")). all people.first.address
eager_load通过执行LEFT OUTER JOIN强制执行加载.
我在国家/地区添加了一个合并,以便您可以更好地控制没有地址的人在结果中出现的位置.
这是我的样子:
people = Person. eager_load(:address). merge(Address.order("coalesce(country,'')")). all (0.5ms) SELECT DISTINCT COUNT(DISTINCT "people"."id") FROM "people" LEFT OUTER JOIN "addresses" ON "addresses"."person_id" = "people"."id" sql (2.1ms) SELECT "people"."id" AS t0_r0,"people"."name" AS t0_r1,"people"."created_at" AS t0_r2,"people"."updated_at" AS t0_r3,"addresses"."id" AS t1_r0,"addresses"."person_id" AS t1_r1,"addresses"."address" AS t1_r2,"addresses"."country" AS t1_r3,"addresses"."created_at" AS t1_r4,"addresses"."updated_at" AS t1_r5 FROM "people" LEFT OUTER JOIN "addresses" ON "addresses"."person_id" = "people"."id" ORDER BY coalesce(addresses.country,'') people.first.address nil people.last.address #<Address:0x007febabb508a8> { :id => 1,:person_id => 4,:address => "24175 Gerhold Prairie",:country => "O",:created_at => Thu,01 Feb 2018 18:47:45 UTC +00:00,:updated_at => Thu,01 Feb 2018 18:47:45 UTC +00:00 }
请注意,访问地址时不会运行任何查询
我会指出你已经通过一个离开外部连接的表来排序,所以你需要决定如何处理空值.