Module: ActiveCollection::Pagination

Defined in:
lib/active_collection/pagination.rb

Defined Under Namespace

Modules: ClassMethods

Constant Summary collapse

PER_PAGE =
30

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#per_pageObject

Defaults to the model class’ per_page.



26
27
28
# File 'lib/active_collection/pagination.rb', line 26

def per_page
  @per_page ||= params[:per_page] || (model_class.respond_to?(:per_page) && model_class.per_page) || self.class.per_page
end

Class Method Details

.included(mod) ⇒ Object



5
6
7
8
9
10
11
12
13
# File 'lib/active_collection/pagination.rb', line 5

def self.included(mod)
  mod.extend ClassMethods

  mod.class_eval do
    alias_method_chain :total_entries, :pagination
    alias_method_chain :size, :pagination
    find_scope :pagination_options
  end
end

Instance Method Details

#as_data_hashObject

TODO clean this up



156
157
158
159
160
161
162
163
164
165
# File 'lib/active_collection/pagination.rb', line 156

def as_data_hash
  data_hash = { "collection" => collection.as_json }
  if paginated?
    data_hash["total_entries"] = total_entries
    data_hash["page"] = current_page
    data_hash["per_page"] = per_page
    data_hash["total_pages"] = total_pages
  end
  data_hash
end

#current_pageObject



21
22
23
# File 'lib/active_collection/pagination.rb', line 21

def current_page
  @current_page ||= params.has_key?(:page) ? (params[:page] || 1).to_i : nil
end

#last_page?Boolean

true if the collection is the last page.

may load total_entries if not already loaded.

Returns:

  • (Boolean)


113
114
115
# File 'lib/active_collection/pagination.rb', line 113

def last_page?
  !out_of_bounds? && next_page.nil?
end

#next_pageObject

current_page + 1 or nil if there is no next page.

loads total_entries if not already loaded.



106
107
108
# File 'lib/active_collection/pagination.rb', line 106

def next_page
  current_page < total_pages ? (current_page + 1) : nil
end

#next_page_collectionObject

New Collection for current_page + 1 or nil

loads total_entries if not already loaded.



125
126
127
# File 'lib/active_collection/pagination.rb', line 125

def next_page_collection
  next_page ? page(next_page, per_page) : nil
end

#offsetObject

Current offset of the paginated collection. If we’re on the first page, it is always 0. If we’re on the 2nd page and there are 30 entries per page, the offset is 30. This property is useful if you want to render ordinals side by side with records in the view: simply start with offset + 1.

loads total_entries if not already loaded.



94
95
96
# File 'lib/active_collection/pagination.rb', line 94

def offset
  (current_page - 1) * per_page
end

#out_of_bounds?Boolean

Helper method that is true when someone tries to fetch a page with a larger number than the last page. Can be used in combination with flashes and redirecting.

loads total_entries if not already loaded.

Returns:

  • (Boolean)


84
85
86
# File 'lib/active_collection/pagination.rb', line 84

def out_of_bounds?
  current_page > total_pages
end

#page(pg, per = self.per_page) ⇒ Object

Create a new collection for the page specified

Optionally accepts a per page parameter which will override the default per_page for the new collection (without changing the current collection).



50
51
52
53
54
# File 'lib/active_collection/pagination.rb', line 50

def page(pg, per = self.per_page)
  new_collection = self.class.new(params.merge(:page => pg))
  new_collection.per_page = per
  new_collection
end

#page!(pg, per = self.per_page) ⇒ Object

Force this collection to a page specified

Optionally accepts a per page parameter which will override the per_page for this collection.



60
61
62
63
64
# File 'lib/active_collection/pagination.rb', line 60

def page!(pg, per = self.per_page)
  raise_if_loaded
  @per_page = per
  @current_page = pg
end

#paginateObject

return a paginated collection if it isn’t already paginated. returns self if already paginated.



68
69
70
# File 'lib/active_collection/pagination.rb', line 68

def paginate
  paginated?? self : page(1)
end

#paginate!Object

forces pagination of self, raising if already loaded. returns current_page if the collection is now paginated returns nil if already paginated



75
76
77
# File 'lib/active_collection/pagination.rb', line 75

def paginate!
  paginated?? nil : page!(1)
end

#paginated?Boolean

if the collection has a page parameter

Returns:

  • (Boolean)


151
152
153
# File 'lib/active_collection/pagination.rb', line 151

def paginated?
  current_page && current_page > 0
end

#previous_pageObject

current_page - 1 or nil if there is no previous page.



99
100
101
# File 'lib/active_collection/pagination.rb', line 99

def previous_page
  current_page > 1 ? (current_page - 1) : nil
end

#previous_page_collectionObject

New Collection for current_page - 1 or nil.



118
119
120
# File 'lib/active_collection/pagination.rb', line 118

def previous_page_collection
  previous_page ? page(previous_page, per_page) : nil
end

#size_with_paginationObject

Loads total entries and calculates the size from that.



32
33
34
35
36
37
38
39
40
41
42
43
44
# File 'lib/active_collection/pagination.rb', line 32

def size_with_pagination
  if paginated?
    if out_of_bounds?
      0
    elsif last_page?
      size_without_pagination % per_page
    else
      per_page
    end
  else
    size_without_pagination
  end
end

#to_xml(options = {}) ⇒ Object

TODO clean this up



168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
# File 'lib/active_collection/pagination.rb', line 168

def to_xml(options = {})
  collect
  options[:indent] ||= 2
  xml = options[:builder] ||= Builder::XmlMarkup.new(:indent => options[:indent])
  xml.instruct! unless options[:skip_instruct]
  xml.tag!(table_name) do
    if paginated?
      xml.total_entries(total_entries, :type => "integer")
      xml.page(current_page, :type => "integer")
      xml.per_page(per_page, :type => "integer")
      xml.total_pages(total_pages, :type => "integer")
    end
    xml.collection(:type => "array") do
      collection.each do |item|
        item.to_xml(:indent => options[:indent], :builder => xml, :skip_instruct => true)
      end
    end
  end
end

#total_entries_with_paginationObject

Always returns the total count regardless of pagination.

Attempts to save a count query if collection is loaded and is the last page.



132
133
134
135
136
137
138
139
140
141
142
143
# File 'lib/active_collection/pagination.rb', line 132

def total_entries_with_pagination
  @total_entries ||=
    if paginated? 
      if loaded? and length < per_page and (current_page == 1 or length > 0)
        offset + length
      else
        total_entries_without_pagination
      end
    else
      total_entries_without_pagination
    end
end

#total_pagesObject

Total number of pages.



146
147
148
# File 'lib/active_collection/pagination.rb', line 146

def total_pages
  (total_entries / per_page.to_f).ceil
end