Skip to content

Instantly share code, notes, and snippets.

@vijedi
Created November 8, 2014 15:14
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save vijedi/13702323c99484109c7e to your computer and use it in GitHub Desktop.
Save vijedi/13702323c99484109c7e to your computer and use it in GitHub Desktop.
Pagination with angular-paginate-anything and kaminari
class Api::BaseController < ApplicationController
include Rivalry::OrganizationScope
respond_to :json
private
def self.paginated_action(options = {})
before_filter(options) do |controller|
if request.headers['Range-Unit'] == 'items' &&
request.headers['Range'].present?
requested_from = nil
requested_to = nil
if request.headers['Range'] =~ /(\d+)-(\d*)/
requested_from, requested_to = $1.to_i, ($2.present? ? $2.to_i : Float::INFINITY)
end
if (requested_from > requested_to)
response.status = 416
headers['Content-Range'] = "*/#{total_items}"
render text: 'invalid pagination range'
return false
end
@kp_per_page = requested_to - requested_from + 1
@kp_page = requested_to / @kp_per_page + 1
end
end
after_filter(options) do |controller|
results = instance_variable_get("@#{controller_name}") # ex @users
if(results.length > 0)
response.status = 206
headers['Accept-Ranges'] = 'items'
headers['Range-Unit'] = 'items'
total_items = results.total_count
current_page = results.current_page
per = @kp_per_page
requested_from = (results.current_page - 1) * per
available_to = (results.length - 1) + requested_from
headers['Content-Range'] = "#{requested_from}-#{available_to}/#{total_items < Float::INFINITY ? total_items : '*'}"
else
response.status = 204
headers['Content-Range'] = "*/0"
end
end
end
end
<div class='paginated_container' ng-controller='PaginatedUserListCtrl'>
<bgf-pagination url='users_url' url-params='user_params' collection='users' per-page="10"></bgf-pagination>
<table>
<tbody>
<tr ng-repeat="user in users">
<td>{{user.name}}</td>
</tr>
</tbody>
</table>
</div>
angular.module('vijedi').
.controller('PaginatedUserListCtrl', ['$scope', function($scope) {
$scope.users_url = '/api/users/.json'; # defined here in case the url needs to be manipulated
$scope.user_params = {
status: 'active'
};
}])
class Api::UsersController < Api::BaseController
paginated_action only: [:index]
def index
@users = User.by_name.where(status: params[:status]) # needs to be assigned so the lookup in the filter works
.page(@kp_page)
.per(@kp_per_page)
respond_with @users
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment