Given an Order model:
has_one :order_build, inverse_of: :order
has_one :build_plan, through: :order_build
scope :ordered_by_build_plan_pending, lambda {
includes(:build_plan)
.merge(BuildPlan.pending_first)
.references(:build_plans)
}
And a BuildPlan model:
has_many :order_builds, dependent: :destroy
has_many :orders, through: :order_builds
scope :pending_first, lambda {
order("CASE build_plans.status WHEN 'pending' THEN 0 ELSE 1 END ASC")
}
In orders controller:
@orders = Order.ordered_by_build_plan_pending.page(params[:page])
Why would @orders.count return 25 (correct) yet @orders.length return 23 (incorrect)? It seems to be to do with the includes in the scope and Kaminari's page scope, but I can't figure out why this is happening.
I am expecting to see 25 records on the index page, but am instead only seeing 23. If I remove the page scope from that initial query it works fine, but I no longer have my paginated collection of 25 records, obviously.
If I actually build up the scope to include all other queries, this number reduces to 21, but the query above is the minimum required to demonstrate the issue.
The full intended query is:
@orders = apply_scopes(Order.without_void)
.includes(:customer, :region, :address)
.search(params[:q])
.ordered_by_build_plan_pending
.ordered(sort_column, sort_direction)
.page(params[:page])
Weirdly, if I run the generated SQL query in a SQL editor, I get the correct 25 results.
The generated query is (incredibly long):
SELECT "orders"."id" AS t0_r0, "orders"."user_id" AS t0_r1, "orders"."customer_id" AS t0_r2, "orders"."order_number" AS t0_r3, "orders"."order_date" AS t0_r4, "orders"."treatment_date" AS t0_r5, "orders"."treatment_time" AS t0_r6, "orders"."ship_date" AS t0_r7, "orders"."patient_ref" AS t0_r8, "orders"."po_number" AS t0_r9, "orders"."created_at" AS t0_r10, "orders"."updated_at" AS t0_r11, "orders"."status" AS t0_r12, "orders"."source" AS t0_r13, "orders"."address_id" AS t0_r14, "orders"."shipping_note" AS t0_r15, "orders"."nordion_ref" AS t0_r16, "orders"."actual_ship_date" AS t0_r17, "orders"."order_type" AS t0_r18, "orders"."delivery_date" AS t0_r19, "orders"."uploaded_at" AS t0_r20, "orders"."waybill_number" AS t0_r21, "orders"."carrier" AS t0_r22, "orders"."same_day_shipping" AS t0_r23, "orders"."treatments_count" AS t0_r24, "orders"."accessories_count" AS t0_r25, "orders"."cancellation_reason_id" AS t0_r26, "orders"."credit_reason_id" AS t0_r27, "orders"."cancellation_reason_type" AS t0_r28, "orders"."finance_status" AS t0_r29, "orders"."delivery_time" AS t0_r30, "orders"."use_surplus_inventory" AS t0_r31, "orders"."cancelled_at" AS t0_r32, "customers"."id" AS t1_r0, "customers"."name" AS t1_r1, "customers"."created_at" AS t1_r2, "customers"."updated_at" AS t1_r3, "customers"."source" AS t1_r4, "customers"."region_id" AS t1_r5, "customers"."currency_code" AS t1_r6, "customers"."active" AS t1_r7, "customers"."finance_id" AS t1_r8, "customers"."preferred_address_id" AS t1_r9, "customers"."nordion_account_number" AS t1_r10, "customers"."archived_at" AS t1_r11, "customers"."customer_type" AS t1_r12, "customers"."settings" AS t1_r13, "regions"."id" AS t2_r0, "regions"."name" AS t2_r1, "regions"."code" AS t2_r2, "regions"."created_at" AS t2_r3, "regions"."updated_at" AS t2_r4, "regions"."short_name" AS t2_r5, "addresses"."id" AS t3_r0, "addresses"."customer_id" AS t3_r1, "addresses"."line1" AS t3_r2, "addresses"."line2" AS t3_r3, "addresses"."city" AS t3_r4, "addresses"."state" AS t3_r5, "addresses"."zip" AS t3_r6, "addresses"."country" AS t3_r7, "addresses"."source" AS t3_r8, "addresses"."created_at" AS t3_r9, "addresses"."updated_at" AS t3_r10, "addresses"."shipping_note" AS t3_r11, "addresses"."deleted_at" AS t3_r12, "addresses"."nordion_ship_to_id" AS t3_r13, "addresses"."line3" AS t3_r14, "addresses"."gp_address_code" AS t3_r15, "addresses"."calibration_data_sheet_required" AS t3_r16, "addresses"."freight_terms" AS t3_r17, "addresses"."incoterms" AS t3_r18, "addresses"."incoterms_location" AS t3_r19, "addresses"."incoterms_year" AS t3_r20, "addresses"."address_type" AS t3_r21, "build_plans"."id" AS t4_r0, "build_plans"."build_number" AS t4_r1, "build_plans"."created_at" AS t4_r2, "build_plans"."updated_at" AS t4_r3, "build_plans"."status" AS t4_r4, "build_plans"."nordion_lot_number" AS t4_r5, "build_plans"."calibration_date" AS t4_r6, "build_plans"."run_date" AS t4_r7, "build_plans"."number_of_ampoules" AS t4_r8, "build_plans"."ampoule_1_mass" AS t4_r9, "build_plans"."ampoule_2_mass" AS t4_r10, "build_plans"."ampoule_3_mass" AS t4_r11, "build_plans"."min_dispensing_limit" AS t4_r12, "build_plans"."max_dispensing_limit" AS t4_r13, "build_plans"."backup_doses" AS t4_r14, "build_plans"."spare_doses" AS t4_r15, "build_plans"."ampoule_1_sa" AS t4_r16, "build_plans"."ampoule_2_sa" AS t4_r17, "build_plans"."ampoule_3_sa" AS t4_r18, "build_plans"."ampoule_1_mass_transfer" AS t4_r19, "build_plans"."ampoule_2_mass_transfer" AS t4_r20, "build_plans"."ampoule_3_mass_transfer" AS t4_r21, "build_plans"."cal_vials_sa" AS t4_r22, "build_plans"."run_number" AS t4_r23, "build_plans"."deleted_at" AS t4_r24, "build_plans"."ampoule_1_name" AS t4_r25, "build_plans"."ampoule_2_name" AS t4_r26, "build_plans"."ampoule_3_name" AS t4_r27, "build_plans"."tmos" AS t4_r28 FROM "orders" LEFT OUTER JOIN "customers" ON "customers"."id" = "orders"."customer_id" LEFT OUTER JOIN "customers" "customers_orders_join" ON "customers_orders_join"."id" = "orders"."customer_id" LEFT OUTER JOIN "regions" ON "regions"."id" = "customers_orders_join"."region_id" LEFT OUTER JOIN "addresses" ON "addresses"."id" = "orders"."address_id" LEFT OUTER JOIN "order_builds" ON "order_builds"."order_id" = "orders"."id" LEFT OUTER JOIN "build_plans" ON "build_plans"."id" = "order_builds"."build_plan_id" AND "build_plans"."deleted_at" IS NULL WHERE "orders"."status" != 'void' AND (customers.name ILIKE '%%' OR orders.order_number::text ILIKE '%%' OR orders.po_number::text ILIKE '%%') AND "build_plans"."deleted_at" IS NULL ORDER BY CASE build_plans.status WHEN 'pending' THEN '0' ELSE '1' END ASC, "orders"."created_at" DESC LIMIT 25 OFFSET 0