Module Cms::Behaviors::Pagination::ClassMethods
In: lib/cms/behaviors/pagination.rb

Methods

Public Instance methods

This is the main paginating finder.

Special parameters for paginating finders

  • :page — REQUIRED, but defaults to 1 if false or nil
  • :per_page — defaults to CurrentModel.per_page (which is 30 if not overridden)
  • :total_entries — use only if you manually count total entries
  • :count — additional options that are passed on to count
  • :finder — name of the ActiveRecord finder used (default: "find")

All other options (conditions, order, …) are forwarded to find and count calls.

[Source]

     # File lib/cms/behaviors/pagination.rb, line 131
131:         def paginate(*args, &block)
132:           options = args.pop
133:           page, per_page, total_entries = parse_pagination_options(options)
134: 
135:           finder = (options[:finder] || 'find').to_s
136:           if finder == 'find'
137:             # an array of IDs may have been given:
138:             total_entries ||= (Array === args.first and args.first.size)
139:             # :all is implicit
140:             args.unshift(:all) if args.empty?
141:           end
142: 
143:           Collection.create(page, per_page, total_entries) do |pager|
144:             count_options = options.except :page, :per_page, :total_entries, :finder
145:             find_options = count_options.except(:count).update(:offset => pager.offset, :limit => pager.per_page) 
146: 
147:             args << find_options
148:             # @options_from_last_find = nil
149:             pager.replace send(finder, *args, &block)
150: 
151:             # magic counting for user convenience:
152:             pager.total_entries = count_for_pagination(count_options, args, finder) unless pager.total_entries
153:           end
154:         end

Protected Instance methods

Does the not-so-trivial job of finding out the total number of entries in the database. It relies on the ActiveRecord count method.

[Source]

     # File lib/cms/behaviors/pagination.rb, line 158
158:           def count_for_pagination(options, args, finder)
159:             excludees = [:count, :order, :limit, :offset, :readonly]
160:             unless options[:select] and options[:select] =~ /^\s*DISTINCT\b/i
161:               excludees << :select # only exclude the select param if it doesn't begin with DISTINCT
162:             end
163:             # count expects (almost) the same options as find
164:             count_options = options.except *excludees
165: 
166:             # merge the hash found in :count
167:             # this allows you to specify :select, :order, or anything else just for the count query
168:             count_options.update options[:count] if options[:count]
169: 
170:             # we may have to scope ...
171:             counter = Proc.new { count(count_options) }
172: 
173:             # we may be in a model or an association proxy!
174:             klass = (@owner and @reflection) ? @reflection.klass : self
175: 
176:             count = if finder.index('find_') == 0 and klass.respond_to?(scoper = finder.sub('find', 'with'))
177:                       # scope_out adds a 'with_finder' method which acts like with_scope, if it's present
178:                       # then execute the count with the scoping provided by the with_finder
179:                       send(scoper, &counter)
180:                     elsif match = /^find_(all_by|by)_([_a-zA-Z]\w*)$/.match(finder)
181:                       # extract conditions from calls like "paginate_by_foo_and_bar"
182:                       attribute_names = extract_attribute_names_from_match(match)
183:                       conditions = construct_attributes_from_arguments(attribute_names, args)
184:                       with_scope(:find => { :conditions => conditions }, &counter)
185:                     else
186:                       counter.call
187:                     end
188: 
189:             count.respond_to?(:length) ? count.length : count
190:           end

[Validate]