Module: PageCursor::ActionControllerExtension
- Defined in:
- lib/page_cursor/cursor.rb
Instance Method Summary collapse
-
#paginate(collection, direction = :asc, limit = 10) ⇒ Object
paginate returns a cursor-enabled pagination.
Instance Method Details
#paginate(collection, direction = :asc, limit = 10) ⇒ Object
paginate returns a cursor-enabled pagination. It uses params and params request variables. It assumes @record’s primary key is sortable.
Example usage: “‘ @cursor, @records = paginate(@records) # in controller <%= pagination_nav @cursor %> # in view “`
and previous (‘before`) primary key, if more records are available.
Caveat: All collection’s order statements are overwritten by paginate.
17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
# File 'lib/page_cursor/cursor.rb', line 17 def paginate(collection, direction = :asc, limit = 10) fail "direction must be :asc or :desc" unless [:asc, :desc].include?(direction) fail "limit must be >= 1" unless limit >= 1 after = params[:after] before = params[:before] fail "only provide one, either params[:after] or params[:before]" if after.present? && before.present? # reference the table's primary key attribute pk = collection.arel_table[collection.primary_key] # return limit + 1 to see if there are more records collection = collection.limit(limit + 1) if after.present? if direction == :asc collection = collection.where(pk.send("gt", after)).reorder(pk.send(:asc)) elsif direction == :desc collection = collection.where(pk.send("lt", after)).reorder(pk.send(:desc)) end r = collection.all return { :after => nil, :before => r.first&.id }, r if r.size <= limit r = r.first(r.size - 1) return { :after => r.last&.id, :before => r.first&.id }, r # --- elsif before.present? if direction == :asc collection = collection.where(pk.send("lt", before)).reorder(pk.send(:desc)) elsif direction == :desc collection = collection.where(pk.send("gt", before)).reorder(pk.send(:asc)) end r = collection.all.reverse return { :after => r.last&.id, :before => nil }, r if r.size <= limit r = r.last(r.size - 1) return { :after => r.last&.id, :before => r.first&.id }, r # --- else # if after and before are both missing r = collection.reorder(pk.send(direction)).all return { :after => nil, :before => nil }, r if r.size <= limit r = r.first(r.size - 1) return { :after => r.last&.id, :before => nil }, r end end |