Class: ErrorStalker::Store::Mongoid::ExceptionGroup::PaginationHelper

Inherits:
Object
  • Object
show all
Defined in:
lib/error_stalker/store/mongoid.rb

Overview

When we display the list of grouped recent exceptions, we paginate them. We also need to display information about the most recent exception report. This helper class wraps paginate, doing a hacked-in :include to get the most recent reports for the requested exception groups without running into the N+1 problem.

Instance Method Summary collapse

Constructor Details

#initialize(criteria) ⇒ PaginationHelper

Wraps criteria in a new PaginationHelper, which will include the most recent exception reports when paginate is called.



237
238
239
# File 'lib/error_stalker/store/mongoid.rb', line 237

def initialize(criteria)
  @criteria = criteria
end

Instance Method Details

#paginate(pagination_opts = {}) ⇒ Object

Override the built-in pagination to support preloading the associated exception reports.



243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
# File 'lib/error_stalker/store/mongoid.rb', line 243

def paginate(pagination_opts = {})
  recent = @criteria.paginate(pagination_opts)
  total_entries = recent.total_entries

  exceptions = ErrorStalker::Store::Mongoid::ExceptionReport.where(:_id.in => recent.map(&:most_recent_report_id))
  # Fake association preloading
  id_map = {}.tap do |h|
    exceptions.each do |ex|
      h[ex.id] = ex
    end
  end

  # Because all the +recent+ stuff is still a scope at this point,
  # we somehow lose the most_recent_report information that we try
  # to assign below the next time we iterate over the
  # scope. Forcing the scope to turn into an array solves that
  # problem, although it means we have to 'fake-paginate' the
  # array before we return it.
  recent = recent.to_a

  recent.each do |r|
    r.most_recent_report = id_map[r.most_recent_report_id]
  end

  recent = recent.paginate(:per_page => pagination_opts[:per_page], :total_entries => total_entries)

  # We're 'fake paginating' this collection, but we still want the
  # page number to be correct. This is the only way to set it
  # without triggering a pagination on records we don't actually have.
  recent.instance_variable_set(:@current_page, WillPaginate::PageNumber(pagination_opts[:page] || 1))
  recent
end