使用ActiveRecord的include方法时避免使用SQL的JOIN吗?

Lin*_*der 1 ruby postgresql activerecord ruby-on-rails

我有这个红宝石代码,导致postgresql提高column "urls.id" must appear in the GROUP BY

Song.
  joins(:artist).
  references(:artist).
  where("artists.active = ?", true).
  group("songs.id").
  includes(:urls)
Run Code Online (Sandbox Code Playgroud)

问题在于添加时Rails正在加入,includes(:urls)而不是运行单独的查询。是否可以强制Rails运行第二个查询来避免此问题?

换一种说法; 我希望Rails在使用JOIN时使用SQL,在使用时使用ActiveRecord::Relation.joins单独的查询ActiveRecord::Relation.includes

删除wherereferences方法使一切顺利,但是后来我无法查询Artists表。

错误消息。

SELECT "songs"."id" AS t0_r0, "songs"."artist_id" AS t0_r1, "songs"."title" AS t0_r2, "songs"."grade" AS t0_r3, "songs"."length" AS t0_r4, "songs"."gigs_count" AS t0_r5, "songs"."clicks" AS t0_r6, "songs"."album_cover_id" AS t0_r7, "songs"."created_at" AS t0_r8, "songs"."updated_at" AS t0_r9, "songs"."position" AS t0_r10, "songs"."services" AS t0_r11, "songs"."moved_id" AS t0_r12, "songs"."details_updated_at" AS t0_r13, "songs"."genres_updated_at" AS t0_r14, "urls"."id" AS t1_r0, "urls"."url" AS t1_r1, "urls"."service_id" AS t1_r2, "urls"."media_id" AS t1_r3, "urls"."media_type" AS t1_r4, "urls"."extra" AS t1_r5 FROM "songs" INNER JOIN "artists" ON "artists"."id" = "songs"."artist_id" LEFT OUTER JOIN "url_bridges" ON "url_bridges"."media_bridge_id" = "songs"."id" AND "url_bridges"."media_bridge_type" = 'Song' LEFT OUTER JOIN "urls" ON "urls"."id" = "url_bridges"."url_id" WHERE (artists.active = 't') AND "songs"."id" IN (944) GROUP BY songs.id
PG::GroupingError: ERROR:  column "urls.id" must appear in the GROUP BY clause or be used in an aggregate function
LINE 1: ...AS t0_r13, "songs"."genres_updated_at" AS t0_r14, "urls"."id...
                                                             ^
: SELECT "songs"."id" AS t0_r0, "songs"."artist_id" AS t0_r1, "songs"."title" AS t0_r2, "songs"."grade" AS t0_r3, "songs"."length" AS t0_r4, "songs"."gigs_count" AS t0_r5, "songs"."clicks" AS t0_r6, "songs"."album_cover_id" AS t0_r7, "songs"."created_at" AS t0_r8, "songs"."updated_at" AS t0_r9, "songs"."position" AS t0_r10, "songs"."services" AS t0_r11, "songs"."moved_id" AS t0_r12, "songs"."details_updated_at" AS t0_r13, "songs"."genres_updated_at" AS t0_r14, "urls"."id" AS t1_r0, "urls"."url" AS t1_r1, "urls"."service_id" AS t1_r2, "urls"."media_id" AS t1_r3, "urls"."media_type" AS t1_r4, "urls"."extra" AS t1_r5 FROM "songs" INNER JOIN "artists" ON "artists"."id" = "songs"."artist_id" LEFT OUTER JOIN "url_bridges" ON "url_bridges"."media_bridge_id" = "songs"."id" AND "url_bridges"."media_bridge_type" = 'Song' LEFT OUTER JOIN "urls" ON "urls"."id" = "url_bridges"."url_id" WHERE (artists.active = 't') AND "songs"."id" IN (944) GROUP BY songs.id
Run Code Online (Sandbox Code Playgroud)

我正在x86_64-unknown-linux-gnu上运行PostgreSQL 9.3.2,由gcc-4.4.real(Ubuntu 4.4.3-4ubuntu5)4.4.3、64位编译。

小智 5

用替换includespreload,文档尚不足以了解其内部构造,但是它将运行第二个查询以渴望加载您指定的关系。我已经将其用于与joins和的相同用例group

Song.
  joins(:artist).
  references(:artist).
  where("artists.active = ?", true).
  group("songs.id").
  preload(:urls)
Run Code Online (Sandbox Code Playgroud)

http://api.rubyonrails.org/classes/ActiveRecord/QueryMethods.html#method-i-preload