4

Howdy I found plenty of examples on how to use LEFT OUTER JOIN, but I can't seem to find a way to access what I have joined. Here is what I mean:

List.featured.
  joins(
    "LEFT OUTER JOIN follows ON (
      follows.followable_id = lists.id AND
      follows.followable_type = 'List' AND
      follows.user_id = #{current_user.id})"
  ).map { |list|
    list.follows # <-- returns all follows, not only the ones from current_user
    ...

In the example I get the follows (it seems) with the join, but then how can I access them? The follows relation will just give me all follows for that list it seems.

Or maybe my mind is fogged :) Thanks!

hakunin
  • 4,041
  • 6
  • 40
  • 57

1 Answers1

3

To eager load follows, you can call includes():

List.featured.includes(:follows).where(:follows => { :user_id => current_user.id })

It generates queries like this:

SELECT
  "lists"."id"          AS t0_r0,
  "lists"."is_featured" AS t0_r1,
  "lists"."created_at"  AS t0_r2,
  "lists"."updated_at"  AS t0_r3,
  "follows"."id"              AS t1_r0,
  "follows"."followable_id"   AS t1_r1,
  "follows"."followable_type" AS t1_r2,
  "follows"."user_id"         AS t1_r3,
  "follows"."created_at"      AS t1_r4,
  "follows"."updated_at"      AS t1_r5
FROM
  "lists"
LEFT OUTER JOIN
  "follows"
ON
  "follows"."followable_id" = "lists"."id" AND
  "follows"."followable_type" = 'List'
WHERE
  "lists"."is_featured" = 't' AND
  "follows"."user_id" = 1
Domon
  • 6,753
  • 1
  • 25
  • 29
  • i believe `includes` does not use join to preform its eager loading, issues a 2nd query using `IN` see - http://guides.rubyonrails.org/active_record_querying.html#eager-loading-associations - i think older versions of rails did use JOIN – house9 Jun 26 '13 at 17:58
  • It does use join if you specify some conditions. The document you provided covers that in chapter 13.2: http://guides.rubyonrails.org/active_record_querying.html#specifying-conditions-on-eager-loaded-associations – Domon Jun 26 '13 at 18:09
  • While this 'works' I only get the lists which are followed by the user :( and I want all lists and join the follows for current user. I was under the impression that LEFT OUTER JOIN does this, but now I am puzzled. Any ideas? – hakunin Jun 27 '13 at 06:28
  • same question as hakunin. how can i actually have the fields from follows in my resulting data structures? or is that not how activerecord works? – Ben Wheeler Jan 12 '16 at 16:09
  • @BenWheeler If you write the code like `Follow.where(...)`, you will get an array of `Follow`s. Is this what you want? – Domon Jan 13 '16 at 08:31