Rails包含导致记录被删除的原因

时间:2018-11-06 15:59:14

标签: ruby-on-rails postgresql activerecord ruby-on-rails-5

给出订单模型:

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)
}

还有一个BuildPlan模型:

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")
}

在订单控制器中:

@orders = Order.ordered_by_build_plan_pending.page(params[:page])

为什么@orders.count返回25(正确)却@orders.length返回23(错误)?似乎与范围内的includes和Kaminari的page范围有关,但我不知道为什么会这样。

我希望在索引页上看到25条记录,但只能看到23条记录。如果我从该初始查询中删除了page范围,则可以正常工作,但是我不再有25个分页集合记录。

如果我实际上将范围扩展为包括所有其他查询,则该数字减少为21,但是上面的查询是证明该问题的最低要求。

完整的预期查询是:

@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])

奇怪的是,如果我在SQL编辑器中运行生成的SQL查询,则会得到正确的25个结果。

生成的查询很长(很长):

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

0 个答案:

没有答案