will_paginate JSON support? will_paginate JSON support? ruby-on-rails ruby-on-rails

will_paginate JSON support?


Something in the lines of:

@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

Once you figure out what format you want, you can always define a to_json method on a WillPaginate::Collection.


Adding Pagination to an API

I found an easy solution to API Json Response Pagination with will_pagination.

start by creating a class method in ApplicationController that will create an after_filter that will set the pagination meta-data in the response headers:

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  endend

Then in the controller we want to add pagination headers we can call it like such:

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  endend

response headers that look like this

> 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


This one helps me:

Add this method to your base API controller.

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

Then, use it on your render method.

render json: posts, meta: pagination_dict(posts)