Pagination in ActiveRecord and SQL

See https://github.com/christianhellsten/arrr-pagination How to do pagination in ActiveRecord and SQL without any external dependencies. Code: ```ruby class Pagination PER_PAGE ||= 10 def self.call(relation:, page: 0, per_page: PER_PAGE) page = page.to_i per_page = per_page.to_i offset = page*per_page array = relation.offset(offset).limit(per_page+1).to_a row_count = relation.count page_count = (row_count.to_f / per_page.to_f).ceil has_previous_page = page > 0 has_next_page = array.size > per_page pagination = OpenStruct.new( page: page, page_count: page_count, previous_page: has_previous_page ? page - 1 : nil, next_page: has_next_page ? page + 1 : nil ) array = array[0..-2] if has_next_page [ array, pagination ] end end ``` Example: ```ruby let(:relation) { Measurement.order("created_at DESC") } it "paginates" do measurements, pagination = Pagination.call(relation: relation, per_page: 1, page: 0) assert_equal 1, measurements.size assert_equal OpenStruct.new(page: 0, page_count: 1, previous_page: nil, next_page: nil), pagination end ``` View: ```slim - if @pagination.previous_page || @pagination.next_page .pagination ul - if @pagination.previous_page li a href=url_for(params.merge(page: nil)) ‹ li a href=url_for(params.merge(page: @pagination.previous_page)) = t('previous') - ([0, @pagination.page-4][email protected]).each do |page| li a href=url_for(params.merge(page: page)) #{page+1} - else li span.muted ‹ li span.muted = t('previous') li span.muted #{t('page')} #{@pagination.page + 1} - if @pagination.next_page - (@pagination.page+1..[@pagination.page_count-1, @pagination.page+4].min).each do |page| li a href=url_for(params.merge(page: page)) #{page+1} li a href=url_for(params.merge(page: @pagination.next_page)) = t('next') li a href=url_for(params.merge(page: @pagination.page_count - 1)) › - else li span.muted = t('next') ```