2012-02-16 7 views
12

tengo esta plantilla:Cómo paginar colecciones de Rabl

# app/views/posts/index.rabl 
collection @posts => :posts 
attributes :id, :title, :subject 
child(:user) { attributes :full_name } 
node(:read) { |post| post.read_by?(@user) } 

bruja regresa:

{ 
    "posts": [ 
     { 
      "post": { 
       "id": 5, 
       "title": "...", 
       "subject": "...", 
       "user": { 
        "full_name": "..." 
       }, 
       "read": true 
      } 
     } 
    ] 
} 

Y me gustaría añadir a añadir algunos parametros de paginación con el fin de prestar este:

{ 
    "posts": [ 
     { 
      "post": { 
       "id": 5, 
       "title": "...", 
       "subject": "...", 
       "user": { 
        "full_name": "..." 
       }, 
       "read": true 
      } 
     } 
    ], 
    "total": 42, 
    "total_pages": 12 
} 

¿Alguna idea? ¡Muchas gracias!

+0

Es mejor agregar información de paginación en la cabecera [ 'Enlace'] gustaría hacer por Github por ejemplo – shingara

+0

estoy totalmente de acuerdo. Sin embargo, en este momento tengo que seguir siendo compatible con algunas API actuales. –

Respuesta

16

Lo siento por mi pregunta de novato, que fue respondida por el README. Aquí está un ejemplo de la paginación:

object false 

node(:total) {|m| @posts.total_count } 
node(:total_pages) {|m| @posts.num_pages } 

child(@posts) do 
    extends "api/v1/posts/show" 
end 

Nota: Estoy usando Kaminari para paginación.

+0

Llamar 'object (false)' cuando el objeto es una matriz no parece funcionar para mí. ¿Hay alguna posibilidad de que puedas ver a qué se parece tu index.rabl? –

1

nota, por will_paginate 3.0.0 las siguientes obras:

node(:total) {|m| @posts.total_entries } 
node(:total_pages) {|m| (@posts.total_entries.to_f/@posts.per_page).ceil } 
node(:page_num){|m| @posts.current_page} 
+0

El cálculo total de las páginas debe ser: 'stuff.total_entries.to_f/stuff.per_page) .ceil', para que la última página no esté llena. – arnab

+0

@arnab gracias, la respuesta se actualizó para reflejar – davidcollom

3

Durante la búsqueda de kaminari y rabl esta es la primera y más o menos único resultado relevante. Como tal, me gustaría dejar aquí una solución de acuerdo con el HAL Specification que genera enlaces como this.

Así que en primer lugar, comenzar con la vista:

# api/v1/posts/index.rabl 
object false 

child(@posts) do 
    extends 'api/v1/posts/show' 
end 

node(:_links) do 
    paginate @posts 
end 

A continuación, proceder a definir el método de paginas:

# app/helpers/api_helper 
module ApiHelper 
    def paginate(collection) 
    current_page_num = collection.current_page 
    last_page_num = collection.total_pages 

    { 
     :first => first_page, 
     :previous => previous_page(current_page_num), 
     :self => current_page(current_page_num), 
     :next => next_page(current_page_num, last_page_num), 
     :last => last_page(last_page_num) 
    } 
    end 

    def first_page 
    { :href => url_for(:page => 1) } 
    end 

    def previous_page(current_page_num) 
    return nil if current_page_num <= 1 
    { :href => url_for(:page => current_page_num-1) } 
    end 

    def current_page(current_page_num) 
    { :href => url_for(:page => current_page_num) } 
    end 

    def next_page(current_page_num, last_page_num) 
    return nil if current_page_num >= last_page_num 
    { :href => url_for(:page => current_page_num+1) } 
    end 

    def last_page(last_page_num) 
    { :href => url_for(:page => last_page_num) } 
    end 
end 

Y, por último, incluir el ayudante en los controladores necesarios. El ayudante podría incluirse en un Api::BaseController, de la que heredan todos los controladores de la API:

helper :api 

No podría haber hecho esto sin solución Zag zag .. 's, por lo .. Muchas gracias!

+1

que rompe la paginación en las vistas normales porque por defecto los rieles incluyen todos los ayudantes –

+0

Luego configure los rieles para que no incluya todos los ayudantes o simplemente renombre el método 'paginate'. – Ashitaka

+0

sí, solo tiene que tenerse en cuenta, porque el comportamiento predeterminado de los rieles está en conflicto con la solución –

0

Esto podría ser lo que está buscando;)

object false 
node :comments do 
    partial('posts/index', object: @posts) 
end 

node(:pagination) do 
    { 
    total:@posts.count, 
    total_pages: 20 
    } 
end 
Cuestiones relacionadas