Al llamar al endpoint /polls/voters.json, utilizando paginación, hemos descubierto que la primera llamada devuelve 25 usuarios como se esperaba, pero la segunda página devuelve 26 usuarios, uno de los cuales ya se devolvió en la primera llamada. Esto es consistente siempre que haya más de 25 usuarios.
El problema está aquí en el plugin de encuestas para Discourse:
https://github.com/discourse/poll/blob/main/plugins/poll/lib/poll.rb#L223
El desplazamiento (offset) se calcula asumiendo que PostgreSQL es exclusivo con un límite de la fila usando BETWEEN, cuando en realidad es inclusivo.
La primera consulta devuelve 25, porque las filas calculadas en realidad comienzan en 1, no en 0.
Mi solución propuesta es tan simple como:
params = {
offset: offset + 1,
offset_plus_limit: offset + limit,
option_digest: opts[:option_id].presence,
}
O, una solución más elegante podría ser usar LIMIT y OFFSET de PostgreSQL.
params = {
limit: limit,
offset: offset,
option_digest: opts[:option_id].presence,
}
WHERE pv.poll_id IN (:poll_ids)
/* where */
) v
ORDER BY digest, CASE WHEN rank = 'Abstain' THEN 1 ELSE CAST(rank AS integer) END, username
LIMIT :limit OFFSET :offset
SQL