2011-01-15 19 views
16

Me pregunto si alguien podría decirme si will_paginate puede admitir JSON de fábrica o si tiene que ser pirateado.will_paginate Soporte de JSON?

Me gustaría agregar datos de página a las respuestas JSON mientras que will_paginate administra la paginación.

Respuesta

38

Algo en la línea de:

@posts = Post.paginate :page => params[:page] 

respond_to do |format| 
    format.json { 
    render :json => { 
     :current_page => @posts.current_page, 
     :per_page => @posts.per_page, 
     :total_entries => @posts.total_entries, 
     :entries => @posts 
    } 
    } 
end 

Una vez que averiguar qué formato desea, siempre se puede definir un método to_json en un WillPaginate :: Colección.

+0

sí, eso es lo que quiero hacer, ahora sé cómo funciona, probablemente devuelva lo que necesito al procesar directamente a JSON, sin embargo, he podido cambiar el formato de esta manera es útil. –

+3

revisa los documentos API de GitHub [1] para una forma mucho mejor de codificar la paginación en tu respuesta (sugerencia: ponla en los encabezados) [1]: http://developer.github.com/v3/#pagination – asymmetric

+2

Cómo ¿Encontraste estos métodos? No están listados en la wiki de will_paginate. – Francisco

1

will_paginate simplemente recupera los registros de una manera cortada. Por lo tanto, solo obtiene una matriz de su base de datos.

Cuando rinde como json, eso es rieles que recorren la matriz de objetos y llaman as_json sobre ellos.

Así que sí, puedes will_paginate render out as json.

+0

Pero supongo que tendré que hackearlo para que incluya el número total de páginas en la respuesta JSON junto con los datos de la paginación. –

+1

eso es todo en la respuesta de Model.paginate, por lo que solo tendrá que buscarlo en la respuesta json. –

+0

También veré eso. Se proporcionó @mislav y un ejemplo de lo que estaba buscando, sin embargo, puedo ver que solo renderizar el resultado estándar como JSON también debe contener la información que necesito. –

1

que recomendamos que vea este Railscast: Pagination with AJAX

+1

No estoy usando RJS así que los datos tienen que estar en la respuesta JSON –

8

Adición de paginación a una API

He encontrado una solución fácil a la API Respuesta JSON paginación con will_pagination.

inicio mediante la creación de un método de clase en ApplicationController que creará un after_filter que establecerá el meta-datos de la paginación en las cabeceras de respuesta:

application_controller.rb

class ApplicationController < ActionController::Base 

    protected 
    def self.set_pagination_headers(name, options = {}) 
    after_filter(options) do |controller| 
     results = instance_variable_get("@#{name}") 
     headers["X-Pagination"] = { 
     total: results.total_entries, 
     total_pages: results.total_pages, 
     first_page: results.current_page == 1, 
     last_page: results.next_page.blank?, 
     previous_page: results.previous_page, 
     next_page: results.next_page, 
     out_of_bounds: results.out_of_bounds?, 
     offset: results.offset 
     }.to_json 
    end 
    end 

end 

Luego, en el controlador que queremos agregar los encabezados de paginación podemos llamarlo así:

widgets_controller.rb

class Api::V1::WidgetsController < Api::V1::BaseController 
    set_pagination_headers :widgets, only: [:index] 

    def index 
    @widgets = Widget.all.paginate(params).order("created_at desc") 
    respond_with @widgets 
    end 

end 

cabeceras de respuesta que se ven así

> Cache-Control:max-age=0, private, must-revalidate 
> Connection:keep-alive Content-Type:application/json; charset=utf-8 
> Etag:"fe70f7bae4c6e5cdea7867aa7fc0c7b4" 
> X-Pagination:{"total":14,"total_pages":1,"first_page":true,"last_page":true,"previous_page":null,"next_page":null,"out_of_bounds":false,"offset":0} 
> Server:thin 1.3.1 codename Triple Espresso 
> Set-Cookie:_widgets_session=BAh7CEkiD3Nlc3Npb25faWQGOgZFRkkiJTAzYjVlNzkwZTIyNzU4YTYwMDU0M2MwOTQ2ZWI3YWU2BjsAVEkiDWxhc3RfdXJsBjsARkkiM2h0dHA6Ly9tYWluYW5kbWUtc3RhZ2luZy5oZXJva3VhcHAuY29tL3VzZXJzLzEGOwBGSSIQX2NzcmZfdG9rZW4GOwBGSSIxdjd0SEp6cVhKamh5YTh1cnBUdmpBb0w5aVA0bS9QTEdON3g1UlFUYnBkND0GOwBG--71b3a24c216a414d8db04f312b5300c818e6bba4; 
> path=/; HttpOnly Transfer-Encoding:Identity 
> X-Request-Id:61b383ade49cba8b24a715a453ed6e1f X-Runtime:0.191485 
> X-Ua-Compatible:IE=Edge,chrome=1 

Source -Adding Pagination to an API

+0

Esta es una gran paginación para una API. No modifique los datos devueltos, coloque la información de paginación en los encabezados. Solución súper limpia, funciona bien con otros como Angular, que quiere una variedad de resultados para un índice/lista/consulta. – Ryan

2

La solución más fácil

def index 
    @posts = Post.all.paginate(:page => params[:page], :per_page => 4) 
    render :json => @posts.to_json(:methods => [:image_url]) 
    end 

sólo tiene que añadir gem, will_pagination

funciona para mí

0

Éste me ayuda:

https://github.com/rails-api/active_model_serializers/blob/master/docs/howto/add_pagination_links.md

adaptado:

Añadir este método para su controlador de API.

def pagination_dict(collection) 
    { 
    current_page: collection.current_page, 
    next_page: collection.next_page, 
    prev_page: collection.prev_page, # use collection.previous_page when using will_paginate 
    total_pages: collection.total_pages, 
    total_count: collection.total_count # use collection.total_entries when using will_paginate 
    } 
end 

Luego, úselo en su método de renderizado.

render json: posts, meta: pagination_dict(posts) 
Cuestiones relacionadas