¿Usar will_paginate en una colección de registros cambia el recuento de resultados paginados?

Tenemos modelos Subscriptiony SubscriptionCart. un Subscription has_many SubscriptionCart_

Tenemos y usamos una relación entre los dos modelos para obtener un Subscriptioncarrito más antiguo donde plan_idcambió al actual Subscription plan_id(en otras palabras, el primer carrito que definió el Subscriptionplan actual)

La Subscriptionrelación es la siguiente:

has_one     :first_version_with_current_plan, -> {
    joins(:subscription)
      .where(subscription_carts: { status: "processed" })
      .where("subscription_carts.plan_id = subscriptions.plan_id")
      .order("subscription_carts.authorized_at ASC")
  }, class_name: "SubscriptionCart", inverse_of: :subscription

La relación anterior devolverá un Subscription(padre) con el primer carrito (hijo) donde plan_idcambió a lo que sea Subscription plan_id.

Estamos usando esa relación en una vista de índice donde estamos usando will_paginate para mostrar los resultados.

controlador:

  def index
    @subscriptions = current_account.subscriptions
      .includes(:first_version_with_current_plan)
      .order("subscription_carts.authorized_at ASC") # relation attribute
      .paginate(page: params[:page], per_page: 20)
      
  end

El problema que tenemos es que antes, el .paginatemétodo @subscriptions.countdevolverá 50, pero al aplicarlo .paginatea la colección, se obtienen menos de 10 resultados totales en la vista.

Sospecho will_paginateque hace una segunda consulta detrás de escena que está rompiendo el conteo de resultados, pero no estoy seguro porque no he encontrado mucho en línea.

¿Hay alguna explicación para esto o alguna solución conocida?

Answer

La paginación debe cambiar el conteo: el objetivo es limitar la cantidad de datos extraídos de la base de datos aplicando límites y compensaciones. Al paginar, el recuento siempre es igual o menor que la per_pageconfiguración; después de todo, solo está obteniendo esa cantidad de filas de la tabla.

Si desea un recuento del número total de registros, debe crear una consulta de recuento separada en el alcance sin paginación:

def index
  scope = current_account.subscriptions
    .includes(:first_version_with_current_plan)
    .order("subscription_carts.authorized_at ASC")
  @count = scope.count
  @subscriptions = scope.paginate(page: params[:page], per_page: 20)
end

Si desea un recuento del número total de registros, debe crear una consulta de recuento separada en el alcance sin paginación o usar cachés de contador en su modelo.