Rails eager loading with WHERE clause results in two SQL queries

50 Views Asked by At

I'm trying to eager load a Course model with some associated models, Community and Package. The relationships between them are as follows:

class Community < ApplicationRecord
  ...
  has_many :courses, dependent: :destroy
end
class Course < ApplicationRecord
  ...
  belongs_to :community, optional: true

  has_many :package_course_relationships, dependent: :destroy
  has_many :packages, through: :package_course_relationships
  has_many :available_packages, -> { available }, through: :package_course_relationships, source: :package
end
class Package < ApplicationRecord
  ...
  has_many :package_course_relationships, dependent: :destroy
  has_many :courses, through: :package_course_relationships

  scope :available, -> { where(archived: false) }
end
class PackageCourseRelationship < ApplicationRecord
  belongs_to :package
  belongs_to :course
end

The problem I am facing is that when calling

Course.includes(:community, :available_packages)
      .where(communities: { is_active: true }, archived: false, is_draft: false, is_completed: false, is_default_template: false, visibility: %i[unlisted public])
      .find(3)

two sql queries are made:

SELECT DISTINCT "courses"."id" FROM "courses" 
LEFT OUTER JOIN "communities" ON "communities"."id" = "courses"."community_id" 
LEFT OUTER JOIN "package_course_relationships" ON "package_course_relationships"."course_id" = "courses"."id" 
LEFT OUTER JOIN "packages" ON "packages"."id" = "package_course_relationships"."package_id" AND "packages"."archived" = $1 
WHERE "communities"."is_active" = $2 AND "courses"."archived" = $3 AND "courses"."is_draft" = $4 AND "courses"."is_completed" = $5 AND "courses"."is_default_template" = $6 AND "courses"."visibility" IN ($7, $8) AND "courses"."id" = $9 
LIMIT $10  
[["archived", false], ["is_active", true], ["archived", false], ["is_draft", false], ["is_completed", false], ["is_default_template", false], ["visibility", "unlisted"], ["visibility", "public"], ["id", 3], ["LIMIT", 1]]
SELECT "courses"."id" AS t0_r0, "courses"."name" AS t0_r1, "courses"."description" AS t0_r2, "courses"."meeting_times" AS t0_r3, "courses"."start_date" AS t0_r4, "courses"."end_date" AS t0_r5, "courses"."is_default" AS t0_r6, "courses"."created_at" AS t0_r7, "courses"."updated_at" AS t0_r8, "courses"."community_id" AS t0_r9, "courses"."is_draft" AS t0_r10, "courses"."is_private" AS t0_r11, "courses"."archived" AS t0_r12, "courses"."is_completed" AS t0_r13, "courses"."program_curriculum_id" AS t0_r14, "courses"."is_template" AS t0_r15, "courses"."is_default_template" AS t0_r16, "courses"."golfer_limit" AS t0_r17, "courses"."marketing_video_url" AS t0_r18, "courses"."is_featured" AS t0_r19, "courses"."photo_url" AS t0_r20, "courses"."organization_id" AS t0_r21, "courses"."lesson_plan_id" AS t0_r22, "courses"."payment_method" AS t0_r23, "courses"."registration_starts_at" AS t0_r24, "courses"."registration_ends_at" AS t0_r25, "courses"."course_category_id" AS t0_r26, "courses"."personalized_video_url" AS t0_r27, "courses"."visibility" AS t0_r28, "communities"."id" AS t1_r0, "communities"."name" AS t1_r1, "communities"."description" AS t1_r2, "communities"."address_id" AS t1_r3, "communities"."created_at" AS t1_r4, "communities"."updated_at" AS t1_r5, "communities"."is_active" AS t1_r6, "communities"."email" AS t1_r7, "communities"."phone_number" AS t1_r8, "communities"."bio" AS t1_r9, "communities"."is_public" AS t1_r10, "communities"."points" AS t1_r11, "communities"."booking_url" AS t1_r12, "communities"."monthly_points" AS t1_r13, "communities"."weekly_points" AS t1_r14, "communities"."support_rating" AS t1_r15, "communities"."representative_id" AS t1_r16, "communities"."community_stage_id" AS t1_r17, "communities"."additional_note" AS t1_r18, "communities"."goals_note" AS t1_r19, "communities"."completed_onboarding" AS t1_r20, "communities"."season_start_date" AS t1_r21, "communities"."season_end_date" AS t1_r22, "communities"."mailing_address" AS t1_r23, "communities"."community_type" AS t1_r24, "communities"."network_date" AS t1_r25, "communities"."purchased_upsell_products" AS t1_r26, "communities"."map_filters" AS t1_r27, "communities"."sales_rep_id" AS t1_r28, "communities"."pinned_ads" AS t1_r29, "communities"."level" AS t1_r30, "communities"."onboarding_checklist_url" AS t1_r31, "communities"."resource_folder_url" AS t1_r32, "communities"."show_onboarding_banner" AS t1_r33, "communities"."selected_stripe_connected_account_id" AS t1_r34, "communities"."license_type" AS t1_r35, "communities"."application_fee" AS t1_r36, "communities"."pipedrive_deal_id" AS t1_r37, "communities"."pipedrive_organization_id" AS t1_r38, "communities"."golf_genius_id" AS t1_r39, "communities"."application_fee_type" AS t1_r40, "communities"."currency_code" AS t1_r41, "communities"."timezone" AS t1_r42, "packages"."id" AS t2_r0, "packages"."name" AS t2_r1, "packages"."description" AS t2_r2, "packages"."price" AS t2_r3, "packages"."archived" AS t2_r4, "packages"."creator_id" AS t2_r5, "packages"."community_id" AS t2_r6, "packages"."created_at" AS t2_r7, "packages"."updated_at" AS t2_r8 FROM "courses"
LEFT OUTER JOIN "communities" ON "communities"."id" = "courses"."community_id"
LEFT OUTER JOIN "package_course_relationships" ON "package_course_relationships"."course_id" = "courses"."id"
LEFT OUTER JOIN "packages" ON "packages"."id" = "package_course_relationships"."package_id" AND "packages"."archived" = $1
WHERE "communities"."is_active" = $2 AND "courses"."archived" = $3 AND "courses"."is_draft" = $4 AND "courses"."is_completed" = $5 AND "courses"."is_default_template" = $6 AND "courses"."visibility" IN ($7, $8) AND "courses"."id" = $9 AND "courses"."id" = $10
[["archived", false], ["is_active", true], ["archived", false], ["is_draft", false], ["is_completed", false], ["is_default_template", false], ["visibility", "unlisted"], ["visibility", "public"], ["id", 3], ["id", 3]]

I am not very experienced with Rails and I think I might have written the ActiveRecord call wrong, but I can't guess why this is resulting in two similar SQL queries.

I don't really know what to try, but I am expecting only one query to be made. It is confusing to me why the first query that only selects the id of the course is made.

0

There are 0 best solutions below