1

je Query Postgres suivante:Rails Paginate requête avec des sous-requêtes dans Postgres

SELECT p.* 
FROM unnest('{19082, 19075, 20705, 18328, 19110, 24965, 18329, 27600 
       , 17804, 20717, 27598, 27599}'::int[]) s(source_id) 
    , LATERAL (
    SELECT * 
    FROM posts 
    WHERE source_id = s.source_id 
    AND deleted_at IS NULL 
    ORDER BY external_created_at DESC 
    LIMIT 100 
    OFFSET 0 
    ) p 
ORDER BY p.external_created_at DESC 
LIMIT 100 
OFFSET 0; 

Et je l'ai converti à une requête ActiveRecord comme ceci:

source_ids = '19082, 19075, 20705, 18328, 19110, 24965, 18329, 27600, 17804, 20717, 27598, 27599' 
subquery = Post.where('source_id = s.source_id AND deleted_at IS NULL') 
      .order('external_created_at DESC') 
Post.select('p.*') 
.from("unnest('{#{source_ids}}'::int[]) s(source_id), LATERAL (#{subquery.to_sql}) p") 
.order('p.external_created_at DESC') 

Je voudrais ajouter Kaminari pagination à cela.

Le problème, cependant, est que pour que la requête fonctionne correctement, je dois ajouter les LIMIT et OFFSET à la requête principale et à la sous-requête.

Si je modifie simplement comme ceci:

source_ids = '19082, 19075, 20705, 18328, 19110, 24965, 18329, 27600, 17804, 20717, 27598, 27599' 
subquery = Post.where('source_id = s.source_id AND deleted_at IS NULL') 
      .order('position, external_created_at DESC') 
      .per(100).page(1) 
Post.select('p.*') 
.from("unnest('{#{source_ids}}'::int[]) s(source_id), LATERAL (#{subquery.to_sql}) p") 
.order('p.position, p.external_created_at DESC') 
.per(100).page(1) 

Je reçois undefined method 'per' for #<Post::ActiveRecord_Relation:0x007f9682f540e0>

Toute pensée ou recommandations?

+1

Avez-vous essayé de changer votre dernière ligne '.page (1) .per (100)'? Note de la page github, 'Notez que la portée n'est pas directement définie sur les modèles, mais est juste une méthode définie sur l'étendue de la page' https://github.com/amatsuda/kaminari –

+0

@HeliosdeGuerra yep c'est exactement ça. Quelle question compliquée pour une erreur stupide. – goddamnyouryan

Répondre

2

Cela peut sembler un peu stupide mais avez-vous essayé d'appeler .page avant .per dans votre requête? Donc Post.where("...").order("...").page(1).per(100)?

Si cela ne fonctionne pas, Kaminari peut paginer des puces. Essayez de convertir vos résultats en un tableau en utilisant .to_a, puis en utilisant la méthode d'assistance paginate_array.

https://github.com/amatsuda/kaminari#paginating-a-generic-array-object

+0

Oh mon dieu, tu as totalement raison. D'oh! – goddamnyouryan