will_paginate_seo 3.0.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (59) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +18 -0
  3. data/README.md +61 -0
  4. data/lib/will_paginate.rb +25 -0
  5. data/lib/will_paginate/active_record.rb +261 -0
  6. data/lib/will_paginate/array.rb +33 -0
  7. data/lib/will_paginate/collection.rb +136 -0
  8. data/lib/will_paginate/core_ext.rb +30 -0
  9. data/lib/will_paginate/data_mapper.rb +100 -0
  10. data/lib/will_paginate/deprecation.rb +55 -0
  11. data/lib/will_paginate/i18n.rb +22 -0
  12. data/lib/will_paginate/locale/en.yml +33 -0
  13. data/lib/will_paginate/mongoid.rb +46 -0
  14. data/lib/will_paginate/page_number.rb +57 -0
  15. data/lib/will_paginate/per_page.rb +27 -0
  16. data/lib/will_paginate/railtie.rb +68 -0
  17. data/lib/will_paginate/sequel.rb +39 -0
  18. data/lib/will_paginate/version.rb +9 -0
  19. data/lib/will_paginate/view_helpers.rb +162 -0
  20. data/lib/will_paginate/view_helpers/action_view.rb +152 -0
  21. data/lib/will_paginate/view_helpers/link_renderer.rb +131 -0
  22. data/lib/will_paginate/view_helpers/link_renderer_base.rb +77 -0
  23. data/lib/will_paginate/view_helpers/merb.rb +26 -0
  24. data/lib/will_paginate/view_helpers/sinatra.rb +41 -0
  25. data/spec/collection_spec.rb +139 -0
  26. data/spec/console +12 -0
  27. data/spec/console_fixtures.rb +28 -0
  28. data/spec/database.yml +22 -0
  29. data/spec/fake_rubygems.rb +18 -0
  30. data/spec/finders/active_record_spec.rb +517 -0
  31. data/spec/finders/activerecord_test_connector.rb +119 -0
  32. data/spec/finders/data_mapper_spec.rb +116 -0
  33. data/spec/finders/data_mapper_test_connector.rb +54 -0
  34. data/spec/finders/mongoid_spec.rb +140 -0
  35. data/spec/finders/sequel_spec.rb +67 -0
  36. data/spec/finders/sequel_test_connector.rb +15 -0
  37. data/spec/fixtures/admin.rb +3 -0
  38. data/spec/fixtures/developer.rb +16 -0
  39. data/spec/fixtures/developers_projects.yml +13 -0
  40. data/spec/fixtures/project.rb +13 -0
  41. data/spec/fixtures/projects.yml +6 -0
  42. data/spec/fixtures/replies.yml +29 -0
  43. data/spec/fixtures/reply.rb +8 -0
  44. data/spec/fixtures/schema.rb +38 -0
  45. data/spec/fixtures/topic.rb +8 -0
  46. data/spec/fixtures/topics.yml +30 -0
  47. data/spec/fixtures/user.rb +2 -0
  48. data/spec/fixtures/users.yml +35 -0
  49. data/spec/matchers/deprecation_matcher.rb +27 -0
  50. data/spec/matchers/phrase_matcher.rb +19 -0
  51. data/spec/matchers/query_count_matcher.rb +36 -0
  52. data/spec/page_number_spec.rb +65 -0
  53. data/spec/per_page_spec.rb +41 -0
  54. data/spec/spec_helper.rb +46 -0
  55. data/spec/view_helpers/action_view_spec.rb +441 -0
  56. data/spec/view_helpers/base_spec.rb +142 -0
  57. data/spec/view_helpers/link_renderer_base_spec.rb +87 -0
  58. data/spec/view_helpers/view_example_group.rb +125 -0
  59. metadata +106 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: e608de709f159fc27535747465f0fa6bd779b4bf
4
+ data.tar.gz: d18884dde89d738847993fbda8db7e44f09684c3
5
+ SHA512:
6
+ metadata.gz: ed057ee640f84f4664e6204c7990ccb714dac2fc3482d608a6dbba852e964e598984cf3e3381490a1a34692e26b91e5f8de87c6f7f68846fb7cf5e3e1ec22d66
7
+ data.tar.gz: 7a62579d4b3912fec8bc2cfb7fa223b4c8f6010496ff2bb897edddc9be5b57f4f33b506536d2dacc6e7646c889e71aeb0177d9acd551698224c629d17801d760
data/LICENSE ADDED
@@ -0,0 +1,18 @@
1
+ Copyright (c) 2009 Mislav Marohnić
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
4
+ this software and associated documentation files (the "Software"), to deal in
5
+ the Software without restriction, including without limitation the rights to
6
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
7
+ the Software, and to permit persons to whom the Software is furnished to do so,
8
+ subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in all
11
+ copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
15
+ FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
16
+ COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
17
+ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
18
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,61 @@
1
+ # will_paginate
2
+
3
+ will_paginate is a pagination library that integrates with Ruby on Rails, Sinatra, Merb, DataMapper and Sequel.
4
+
5
+ Installation:
6
+
7
+ ``` ruby
8
+ ## Gemfile for Rails 3, Rails 4, Sinatra, and Merb
9
+ gem 'will_paginate', '~> 3.0'
10
+ ```
11
+
12
+ See [installation instructions][install] on the wiki for more info.
13
+
14
+
15
+ ## Basic will_paginate use
16
+
17
+ ``` ruby
18
+ ## perform a paginated query:
19
+ @posts = Post.paginate(:page => params[:page])
20
+
21
+ # or, use an explicit "per page" limit:
22
+ Post.paginate(:page => params[:page], :per_page => 30)
23
+
24
+ ## render page links in the view:
25
+ <%= will_paginate @posts %>
26
+ ```
27
+
28
+ And that's it! You're done. You just need to add some CSS styles to [make those pagination links prettier][css].
29
+
30
+ You can customize the default "per_page" value:
31
+
32
+ ``` ruby
33
+ # for the Post model
34
+ class Post
35
+ self.per_page = 10
36
+ end
37
+
38
+ # set per_page globally
39
+ WillPaginate.per_page = 10
40
+ ```
41
+
42
+ New in Active Record 3:
43
+
44
+ ``` ruby
45
+ # paginate in Active Record now returns a Relation
46
+ Post.where(:published => true).paginate(:page => params[:page]).order('id DESC')
47
+
48
+ # the new, shorter page() method
49
+ Post.page(params[:page]).order('created_at DESC')
50
+ ```
51
+
52
+ See [the wiki][wiki] for more documentation. [Ask on the group][group] if you have usage questions. [Report bugs][issues] on GitHub.
53
+
54
+ Happy paginating.
55
+
56
+
57
+ [wiki]: https://github.com/mislav/will_paginate/wiki
58
+ [install]: https://github.com/mislav/will_paginate/wiki/Installation "will_paginate installation"
59
+ [group]: http://groups.google.com/group/will_paginate "will_paginate discussion and support group"
60
+ [issues]: https://github.com/mislav/will_paginate/issues
61
+ [css]: http://mislav.uniqpath.com/will_paginate/
@@ -0,0 +1,25 @@
1
+ # You will paginate!
2
+ module WillPaginate
3
+ end
4
+
5
+ if defined?(Rails::Railtie)
6
+ require 'will_paginate/railtie'
7
+ elsif defined?(Rails::Initializer)
8
+ raise "will_paginate 3.0 is not compatible with Rails 2.3 or older"
9
+ end
10
+
11
+ if defined?(Merb::AbstractController)
12
+ require 'will_paginate/view_helpers/merb'
13
+
14
+ Merb::BootLoader.before_app_loads do
15
+ adapters = { :datamapper => 'data_mapper', :activerecord => 'active_record', :sequel => 'sequel' }
16
+ # auto-load the right ORM adapter
17
+ if adapter = adapters[Merb.orm]
18
+ require "will_paginate/#{adapter}"
19
+ end
20
+ end
21
+ end
22
+
23
+ if defined?(Sinatra) and Sinatra.respond_to? :register
24
+ require 'will_paginate/view_helpers/sinatra'
25
+ end
@@ -0,0 +1,261 @@
1
+ require 'will_paginate/per_page'
2
+ require 'will_paginate/page_number'
3
+ require 'will_paginate/collection'
4
+ require 'active_record'
5
+ begin
6
+ require 'active_record/deprecated_finders'
7
+ rescue LoadError
8
+ # only for Rails 4.1
9
+ end
10
+
11
+ module WillPaginate
12
+ # = Paginating finders for ActiveRecord models
13
+ #
14
+ # WillPaginate adds +paginate+, +per_page+ and other methods to
15
+ # ActiveRecord::Base class methods and associations.
16
+ #
17
+ # In short, paginating finders are equivalent to ActiveRecord finders; the
18
+ # only difference is that we start with "paginate" instead of "find" and
19
+ # that <tt>:page</tt> is required parameter:
20
+ #
21
+ # @posts = Post.paginate :all, :page => params[:page], :order => 'created_at DESC'
22
+ #
23
+ module ActiveRecord
24
+ # makes a Relation look like WillPaginate::Collection
25
+ module RelationMethods
26
+ include WillPaginate::CollectionMethods
27
+
28
+ attr_accessor :current_page
29
+ attr_writer :total_entries, :wp_count_options
30
+
31
+ def per_page(value = nil)
32
+ if value.nil? then limit_value
33
+ else limit(value)
34
+ end
35
+ end
36
+
37
+ # TODO: solve with less relation clones and code dups
38
+ def limit(num)
39
+ rel = super
40
+ if rel.current_page
41
+ rel.offset rel.current_page.to_offset(rel.limit_value).to_i
42
+ else
43
+ rel
44
+ end
45
+ end
46
+
47
+ # dirty hack to enable `first` after `limit` behavior above
48
+ def first(*args)
49
+ if current_page
50
+ rel = clone
51
+ rel.current_page = nil
52
+ rel.first(*args)
53
+ else
54
+ super
55
+ end
56
+ end
57
+
58
+ # fix for Rails 3.0
59
+ def find_last
60
+ if !loaded? and offset_value || limit_value
61
+ @last ||= to_a.last
62
+ else
63
+ super
64
+ end
65
+ end
66
+
67
+ def offset(value = nil)
68
+ if value.nil? then offset_value
69
+ else super(value)
70
+ end
71
+ end
72
+
73
+ def total_entries
74
+ @total_entries ||= begin
75
+ if loaded? and size < limit_value and (current_page == 1 or size > 0)
76
+ offset_value + size
77
+ else
78
+ @total_entries_queried = true
79
+ result = count
80
+ result = result.size if result.respond_to?(:size) and !result.is_a?(Integer)
81
+ result
82
+ end
83
+ end
84
+ end
85
+
86
+ def count(*args)
87
+ if limit_value
88
+ excluded = [:order, :limit, :offset, :reorder]
89
+ excluded << :includes unless eager_loading?
90
+ rel = self.except(*excluded)
91
+ # TODO: hack. decide whether to keep
92
+ rel = rel.apply_finder_options(@wp_count_options) if defined? @wp_count_options
93
+
94
+ column_name = (select_for_count(rel) || :all)
95
+ rel.count(column_name)
96
+ else
97
+ super(*args)
98
+ end
99
+ end
100
+
101
+ # workaround for Active Record 3.0
102
+ def size
103
+ if !loaded? and limit_value and group_values.empty?
104
+ [super, limit_value].min
105
+ else
106
+ super
107
+ end
108
+ end
109
+
110
+ # overloaded to be pagination-aware
111
+ def empty?
112
+ if !loaded? and offset_value
113
+ result = count
114
+ result = result.size if result.respond_to?(:size) and !result.is_a?(Integer)
115
+ result <= offset_value
116
+ else
117
+ super
118
+ end
119
+ end
120
+
121
+ def clone
122
+ copy_will_paginate_data super
123
+ end
124
+
125
+ # workaround for Active Record 3.0
126
+ def scoped(options = nil)
127
+ copy_will_paginate_data super
128
+ end
129
+
130
+ def to_a
131
+ if current_page.nil? then super # workaround for Active Record 3.0
132
+ else
133
+ ::WillPaginate::Collection.create(current_page, limit_value) do |col|
134
+ col.replace super
135
+ col.total_entries ||= total_entries
136
+ end
137
+ end
138
+ end
139
+
140
+ private
141
+
142
+ def copy_will_paginate_data(other)
143
+ other.current_page = current_page unless other.current_page
144
+ other.total_entries = nil if defined? @total_entries_queried
145
+ other.wp_count_options = @wp_count_options if defined? @wp_count_options
146
+ other
147
+ end
148
+
149
+ def select_for_count(rel)
150
+ if rel.select_values.present?
151
+ select = rel.select_values.join(", ")
152
+ select if select !~ /[,*]/
153
+ end
154
+ end
155
+ end
156
+
157
+ module Pagination
158
+ def paginate(options)
159
+ options = options.dup
160
+ pagenum = options.fetch(:page) { raise ArgumentError, ":page parameter required" }
161
+ per_page = options.delete(:per_page) || self.per_page
162
+ total = options.delete(:total_entries)
163
+
164
+ count_options = options.delete(:count)
165
+ options.delete(:page)
166
+
167
+ rel = limit(per_page.to_i).page(pagenum)
168
+ rel = rel.apply_finder_options(options) if options.any?
169
+ rel.wp_count_options = count_options if count_options
170
+ rel.total_entries = total.to_i unless total.blank?
171
+ rel
172
+ end
173
+
174
+ def page(num)
175
+ rel = if ::ActiveRecord::Relation === self
176
+ self
177
+ elsif !defined?(::ActiveRecord::Scoping) or ::ActiveRecord::Scoping::ClassMethods.method_defined? :with_scope
178
+ # Active Record 3
179
+ scoped
180
+ else
181
+ # Active Record 4
182
+ all
183
+ end
184
+
185
+ rel = rel.extending(RelationMethods)
186
+ pagenum = ::WillPaginate::PageNumber(num.nil? ? 1 : num)
187
+ per_page = rel.limit_value || self.per_page
188
+ rel = rel.offset(pagenum.to_offset(per_page).to_i)
189
+ rel = rel.limit(per_page) unless rel.limit_value
190
+ rel.current_page = pagenum
191
+ rel
192
+ end
193
+ end
194
+
195
+ module BaseMethods
196
+ # Wraps +find_by_sql+ by simply adding LIMIT and OFFSET to your SQL string
197
+ # based on the params otherwise used by paginating finds: +page+ and
198
+ # +per_page+.
199
+ #
200
+ # Example:
201
+ #
202
+ # @developers = Developer.paginate_by_sql ['select * from developers where salary > ?', 80000],
203
+ # :page => params[:page], :per_page => 3
204
+ #
205
+ # A query for counting rows will automatically be generated if you don't
206
+ # supply <tt>:total_entries</tt>. If you experience problems with this
207
+ # generated SQL, you might want to perform the count manually in your
208
+ # application.
209
+ #
210
+ def paginate_by_sql(sql, options)
211
+ pagenum = options.fetch(:page) { raise ArgumentError, ":page parameter required" } || 1
212
+ per_page = options[:per_page] || self.per_page
213
+ total = options[:total_entries]
214
+
215
+ WillPaginate::Collection.create(pagenum, per_page, total) do |pager|
216
+ query = sanitize_sql(sql.dup)
217
+ original_query = query.dup
218
+ oracle = self.connection.adapter_name =~ /^(oracle|oci$)/i
219
+
220
+ # add limit, offset
221
+ if oracle
222
+ query = <<-SQL
223
+ SELECT * FROM (
224
+ SELECT rownum rnum, a.* FROM (#{query}) a
225
+ WHERE rownum <= #{pager.offset + pager.per_page}
226
+ ) WHERE rnum >= #{pager.offset}
227
+ SQL
228
+ else
229
+ query << " LIMIT #{pager.per_page} OFFSET #{pager.offset}"
230
+ end
231
+
232
+ # perfom the find
233
+ pager.replace find_by_sql(query)
234
+
235
+ unless pager.total_entries
236
+ count_query = original_query.sub /\bORDER\s+BY\s+[\w`,\s.]+$/mi, ''
237
+ count_query = "SELECT COUNT(*) FROM (#{count_query})"
238
+ count_query << ' AS count_table' unless oracle
239
+ # perform the count query
240
+ pager.total_entries = count_by_sql(count_query)
241
+ end
242
+ end
243
+ end
244
+ end
245
+
246
+ # mix everything into Active Record
247
+ ::ActiveRecord::Base.extend PerPage
248
+ ::ActiveRecord::Base.extend Pagination
249
+ ::ActiveRecord::Base.extend BaseMethods
250
+
251
+ klasses = [::ActiveRecord::Relation]
252
+ if defined? ::ActiveRecord::Associations::CollectionProxy
253
+ klasses << ::ActiveRecord::Associations::CollectionProxy
254
+ else
255
+ klasses << ::ActiveRecord::Associations::AssociationCollection
256
+ end
257
+
258
+ # support pagination on associations and scopes
259
+ klasses.each { |klass| klass.send(:include, Pagination) }
260
+ end
261
+ end
@@ -0,0 +1,33 @@
1
+ require 'will_paginate/collection'
2
+
3
+ class Array
4
+ # Paginates a static array (extracting a subset of it). The result is a
5
+ # WillPaginate::Collection instance, which is an array with a few more
6
+ # properties about its paginated state.
7
+ #
8
+ # Parameters:
9
+ # * <tt>:page</tt> - current page, defaults to 1
10
+ # * <tt>:per_page</tt> - limit of items per page, defaults to 30
11
+ # * <tt>:total_entries</tt> - total number of items in the array, defaults to
12
+ # <tt>array.length</tt> (obviously)
13
+ #
14
+ # Example:
15
+ # arr = ['a', 'b', 'c', 'd', 'e']
16
+ # paged = arr.paginate(:per_page => 2) #-> ['a', 'b']
17
+ # paged.total_entries #-> 5
18
+ # arr.paginate(:page => 2, :per_page => 2) #-> ['c', 'd']
19
+ # arr.paginate(:page => 3, :per_page => 2) #-> ['e']
20
+ #
21
+ # This method was originally {suggested by Desi
22
+ # McAdam}[http://www.desimcadam.com/archives/8] and later proved to be the
23
+ # most useful method of will_paginate library.
24
+ def paginate(options = {})
25
+ page = options[:page] || 1
26
+ per_page = options[:per_page] || WillPaginate.per_page
27
+ total = options[:total_entries] || self.length
28
+
29
+ WillPaginate::Collection.create(page, per_page, total) do |pager|
30
+ pager.replace self[pager.offset, pager.per_page].to_a
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,136 @@
1
+ require 'will_paginate/per_page'
2
+ require 'will_paginate/page_number'
3
+
4
+ module WillPaginate
5
+ # Any will_paginate-compatible collection should have these methods:
6
+ #
7
+ # current_page, per_page, offset, total_entries, total_pages
8
+ #
9
+ # It can also define some of these optional methods:
10
+ #
11
+ # out_of_bounds?, previous_page, next_page
12
+ #
13
+ # This module provides few of these methods.
14
+ module CollectionMethods
15
+ def total_pages
16
+ total_entries.zero? ? 1 : (total_entries / per_page.to_f).ceil
17
+ end
18
+
19
+ # current_page - 1 or nil if there is no previous page
20
+ def previous_page
21
+ current_page > 1 ? (current_page - 1) : nil
22
+ end
23
+
24
+ # current_page + 1 or nil if there is no next page
25
+ def next_page
26
+ current_page < total_pages ? (current_page + 1) : nil
27
+ end
28
+
29
+ # Helper method that is true when someone tries to fetch a page with a
30
+ # larger number than the last page. Can be used in combination with flashes
31
+ # and redirecting.
32
+ def out_of_bounds?
33
+ current_page > total_pages
34
+ end
35
+ end
36
+
37
+ # = The key to pagination
38
+ # Arrays returned from paginating finds are, in fact, instances of this little
39
+ # class. You may think of WillPaginate::Collection as an ordinary array with
40
+ # some extra properties. Those properties are used by view helpers to generate
41
+ # correct page links.
42
+ #
43
+ # WillPaginate::Collection also assists in rolling out your own pagination
44
+ # solutions: see +create+.
45
+ #
46
+ # If you are writing a library that provides a collection which you would like
47
+ # to conform to this API, you don't have to copy these methods over; simply
48
+ # make your plugin/gem dependant on this library and do:
49
+ #
50
+ # require 'will_paginate/collection'
51
+ # # WillPaginate::Collection is now available for use
52
+ class Collection < Array
53
+ include CollectionMethods
54
+
55
+ attr_reader :current_page, :per_page, :total_entries
56
+
57
+ # Arguments to the constructor are the current page number, per-page limit
58
+ # and the total number of entries. The last argument is optional because it
59
+ # is best to do lazy counting; in other words, count *conditionally* after
60
+ # populating the collection using the +replace+ method.
61
+ def initialize(page, per_page = WillPaginate.per_page, total = nil)
62
+ @current_page = WillPaginate::PageNumber(page)
63
+ @per_page = per_page.to_i
64
+ self.total_entries = total if total
65
+ end
66
+
67
+ # Just like +new+, but yields the object after instantiation and returns it
68
+ # afterwards. This is very useful for manual pagination:
69
+ #
70
+ # @entries = WillPaginate::Collection.create(1, 10) do |pager|
71
+ # result = Post.find(:all, :limit => pager.per_page, :offset => pager.offset)
72
+ # # inject the result array into the paginated collection:
73
+ # pager.replace(result)
74
+ #
75
+ # unless pager.total_entries
76
+ # # the pager didn't manage to guess the total count, do it manually
77
+ # pager.total_entries = Post.count
78
+ # end
79
+ # end
80
+ #
81
+ # The possibilities with this are endless. For another example, here is how
82
+ # WillPaginate used to define pagination for Array instances:
83
+ #
84
+ # Array.class_eval do
85
+ # def paginate(page = 1, per_page = 15)
86
+ # WillPaginate::Collection.create(page, per_page, size) do |pager|
87
+ # pager.replace self[pager.offset, pager.per_page].to_a
88
+ # end
89
+ # end
90
+ # end
91
+ #
92
+ # The Array#paginate API has since then changed, but this still serves as a
93
+ # fine example of WillPaginate::Collection usage.
94
+ def self.create(page, per_page, total = nil)
95
+ pager = new(page, per_page, total)
96
+ yield pager
97
+ pager
98
+ end
99
+
100
+ # Current offset of the paginated collection. If we're on the first page,
101
+ # it is always 0. If we're on the 2nd page and there are 30 entries per page,
102
+ # the offset is 30. This property is useful if you want to render ordinals
103
+ # side by side with records in the view: simply start with offset + 1.
104
+ def offset
105
+ current_page.to_offset(per_page).to_i
106
+ end
107
+
108
+ def total_entries=(number)
109
+ @total_entries = number.to_i
110
+ end
111
+
112
+ # This is a magic wrapper for the original Array#replace method. It serves
113
+ # for populating the paginated collection after initialization.
114
+ #
115
+ # Why magic? Because it tries to guess the total number of entries judging
116
+ # by the size of given array. If it is shorter than +per_page+ limit, then we
117
+ # know we're on the last page. This trick is very useful for avoiding
118
+ # unnecessary hits to the database to do the counting after we fetched the
119
+ # data for the current page.
120
+ #
121
+ # However, after using +replace+ you should always test the value of
122
+ # +total_entries+ and set it to a proper value if it's +nil+. See the example
123
+ # in +create+.
124
+ def replace(array)
125
+ result = super
126
+
127
+ # The collection is shorter then page limit? Rejoice, because
128
+ # then we know that we are on the last page!
129
+ if total_entries.nil? and length < per_page and (current_page == 1 or length > 0)
130
+ self.total_entries = offset + length
131
+ end
132
+
133
+ result
134
+ end
135
+ end
136
+ end