ruby-on-rails - page - will_paginate rails tutorial
will_paginate soporte JSON? (6)
Me pregunto si alguien podría, por favor, decirme si will_paginate puede admitir JSON fuera de la caja o si esto tiene que ser hackeado.
Me gustaría agregar datos de página a las respuestas JSON mientras will_paginate administra la paginación.
Algo en las líneas 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 to_json
qué formato quieres, siempre puedes definir un método to_json
en un WillPaginate :: Collection.
Este me ayuda
Agregue este método a su controlador API base.
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, úsalo en tu método de renderizado.
render json: posts, meta: pagination_dict(posts)
Te recomiendo que veas este Railscast: Paginación con AJAX.
will_paginate solo recupera los registros de forma dividida. Así que solo obtiene una matriz de su base de datos.
Cuando se procesa como json, los rieles pasan por encima de la matriz de objetos y llaman a as_json en ellos.
Así que sí, puedes will_paginate renderizando como json.
Adición de paginación a una API
Encontré una solución fácil para la API Json Response Pagination con will_pagination.
Comience creando un método de clase en ApplicationController
que creará un after_filter
que establecerá los metadatos de paginación en los encabezados 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 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
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
Solo necesitas agregar la gem ''will_paginate''
Esto funciona para mi.