From 07f8dba7f2c2e7a9ff43290b24b40d91cdc45107 Mon Sep 17 00:00:00 2001 From: albert Date: Tue, 21 Jun 2011 12:20:22 -0400 Subject: [PATCH] work --- Gemfile | 1 - Gemfile.lock | 8 -- app/controllers/post_versions_controller.rb | 3 +- app/controllers/posts_controller.rb | 5 +- app/helpers/pagination_helper.rb | 63 ++++----- app/logical/post_sets/base.rb | 80 ----------- app/logical/post_sets/error.rb | 4 - app/logical/post_sets/favorite.rb | 33 ----- app/logical/post_sets/numbered.rb | 51 ------- app/logical/post_sets/pool.rb | 30 ---- app/logical/post_sets/post.rb | 63 --------- app/logical/post_sets/sequential.rb | 45 ------ app/logical/post_sets/wiki_page.rb | 29 ---- app/models/post.rb | 18 ++- app/presenters/post_set_presenter.rb | 10 +- app/views/post_versions/index.html.erb | 128 +++++++----------- config/initializers/lib.rb | 1 + lib/danbooru/paginator.rb | 6 + .../paginator/active_record_extension.rb | 68 ++++++++++ .../paginator/collection_extension.rb | 6 + .../numbered_collection_extension.rb | 27 ++++ .../sequential_collection_extension.rb | 51 +++++++ 22 files changed, 262 insertions(+), 468 deletions(-) delete mode 100644 app/logical/post_sets/base.rb delete mode 100644 app/logical/post_sets/error.rb delete mode 100644 app/logical/post_sets/favorite.rb delete mode 100644 app/logical/post_sets/numbered.rb delete mode 100644 app/logical/post_sets/pool.rb delete mode 100644 app/logical/post_sets/post.rb delete mode 100644 app/logical/post_sets/sequential.rb delete mode 100644 app/logical/post_sets/wiki_page.rb create mode 100644 config/initializers/lib.rb create mode 100644 lib/danbooru/paginator.rb create mode 100644 lib/danbooru/paginator/active_record_extension.rb create mode 100644 lib/danbooru/paginator/collection_extension.rb create mode 100644 lib/danbooru/paginator/numbered_collection_extension.rb create mode 100644 lib/danbooru/paginator/sequential_collection_extension.rb diff --git a/Gemfile b/Gemfile index 254945c6d..a3bd122c4 100644 --- a/Gemfile +++ b/Gemfile @@ -19,5 +19,4 @@ gem "simple_form" gem "mechanize" gem "nokogiri" gem "meta_search", :git => "git://github.com/ernie/meta_search.git" -gem "will_paginate", :git => "git://github.com/mmack/will_paginate.git", :branch => "rails3.1" gem "silent-postgres" diff --git a/Gemfile.lock b/Gemfile.lock index a81fee34a..f424c75d0 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -7,13 +7,6 @@ GIT activerecord (~> 3.1.0.alpha) activesupport (~> 3.1.0.alpha) -GIT - remote: git://github.com/mmack/will_paginate.git - revision: 5816b4e8d4382b4b167621a9aea4b8fe72983c37 - branch: rails3.1 - specs: - will_paginate (3.1.0) - GIT remote: http://github.com/EmmanuelOga/ffaker.git revision: 52feff4ecddbe8834b63beb122b153b65833e309 @@ -143,4 +136,3 @@ DEPENDENCIES simple_form simplecov super_exception_notifier - will_paginate! diff --git a/app/controllers/post_versions_controller.rb b/app/controllers/post_versions_controller.rb index 01bbba81f..f5f2b2760 100644 --- a/app/controllers/post_versions_controller.rb +++ b/app/controllers/post_versions_controller.rb @@ -1,6 +1,5 @@ class PostVersionsController < ApplicationController def index - @search = PostVersion.search(params[:search]) - @post_versions = @search.paginate(:page => params[:page], :order => "updated_at DESC") + @search = PostVersion.search(params[:search]).paginate(params[:paginate]) end end diff --git a/app/controllers/posts_controller.rb b/app/controllers/posts_controller.rb index f8847b24c..d80164d4f 100644 --- a/app/controllers/posts_controller.rb +++ b/app/controllers/posts_controller.rb @@ -4,9 +4,8 @@ class PostsController < ApplicationController respond_to :html, :xml, :json def index - @post_set = PostSets::Base.new(params) - extend_post_set(@post_set) - respond_with(@post_set) + @posts = Post.search(params[:search]).paginate(params[:page]) + respond_with(@posts) end def show diff --git a/app/helpers/pagination_helper.rb b/app/helpers/pagination_helper.rb index fa5af5a4d..cb17822f5 100644 --- a/app/helpers/pagination_helper.rb +++ b/app/helpers/pagination_helper.rb @@ -1,64 +1,61 @@ module PaginationHelper - def smart_paginator(set, &block) - if params[:page] && set.page > 1000 - set.extend(PostSets::Sequential) - sequential_paginator(set) + def smart_paginator(records, &block) + if records.is_sequential_paginator? || params[:page].to_i > 200 + sequential_paginator(records) else - set.extend(PostSets::Numbered) - numbered_paginator(set, &block) + numbered_paginator(records, &block) end end - def sequential_paginator(set) + def sequential_paginator(records) html = "" - unless set.is_first_page? - html << '
  • ' + link_to("« Previous", params.merge(:after_id => set.first_id)) + '
  • ' + unless records.is_first_page? + html << '
  • ' + link_to("« Previous", params.merge(:after_id => records.first_id)) + '
  • ' end - unless set.is_last_page? - html << '
  • ' + link_to("Next »", params.merge(:before_id => set.last_id)) + '
  • ' + unless records.is_last_page? + html << '
  • ' + link_to("Next »", params.merge(:before_id => records.last_id)) + '
  • ' end html << "
    " html.html_safe end - def numbered_paginator(set, &block) + def numbered_paginator(records, &block) html = "" window = 3 - if set.total_pages <= (window * 2) + 5 - 1.upto(set.total_pages) do |page| - html << numbered_paginator_item(page, set.current_page, &block) + if records.total_pages <= (window * 2) + 5 + 1.upto(records.total_pages) do |page| + html << numbered_paginator_item(page, records.current_page, &block) end - elsif set.current_page <= window + 2 - 1.upto(set.current_page + window) do |page| - html << numbered_paginator_item(page, set.current_page, &block) + elsif records.current_page <= window + 2 + 1.upto(records.current_page + window) do |page| + html << numbered_paginator_item(page, records.current_page, &block) end - html << numbered_paginator_item("...", set.current_page, &block) - html << numbered_paginator_final_item(set.total_pages, set.current_page, &block) - - elsif set.current_page >= set.total_pages - (window + 1) - html << numbered_paginator_item(1, set.current_page, &block) - html << numbered_paginator_item("...", set.current_page, &block) - (set.current_page - window).upto(set.total_pages) do |page| - html << numbered_paginator_item(page, set.current_page, &block) + html << numbered_paginator_item("...", records.current_page, &block) + html << numbered_paginator_final_item(records.total_pages, records.current_page, &block) + elsif records.current_page >= records.total_pages - (window + 1) + html << numbered_paginator_item(1, records.current_page, &block) + html << numbered_paginator_item("...", records.current_page, &block) + (records.current_page - window).upto(records.total_pages) do |page| + html << numbered_paginator_item(page, records.current_page, &block) end else - html << numbered_paginator_item(1, set.current_page, &block) - html << numbered_paginator_item("...", set.current_page, &block) - (set.current_page - window).upto(set.current_page + window) do |page| - html << numbered_paginator_item(page, set.current_page, &block) + html << numbered_paginator_item(1, records.current_page, &block) + html << numbered_paginator_item("...", records.current_page, &block) + (records.current_page - window).upto(records.current_page + window) do |page| + html << numbered_paginator_item(page, records.current_page, &block) end - html << numbered_paginator_item("...", set.current_page, &block) - html << numbered_paginator_final_item(set.total_pages, set.current_page, &block) + html << numbered_paginator_item("...", records.current_page, &block) + html << numbered_paginator_final_item(records.total_pages, records.current_page, &block) end html << "" html.html_safe end def numbered_paginator_final_item(total_pages, current_page, &block) - if total_pages <= 1000 + if total_pages <= 200 numbered_paginator_item(total_pages, current_page, &block) else "" diff --git a/app/logical/post_sets/base.rb b/app/logical/post_sets/base.rb deleted file mode 100644 index d43c11356..000000000 --- a/app/logical/post_sets/base.rb +++ /dev/null @@ -1,80 +0,0 @@ -# A PostSet represents a paginated slice of posts. It is used in conjunction -# with the helpers to render the paginator. -# -# Usage: -# -# @post_set = PostSets::Base.new(params) -# @post_set.extend(PostSets::Sequential) -# @post_set.extend(PostSets::Post) - -module PostSets - class Base - attr_reader :params, :posts - delegate :to_xml, :to_json, :to => :posts - - def initialize(params) - @params = params - end - - # Should a return a paginated array of posts. This means it should have - # at most elements. - def posts - raise NotImplementedError - end - - # Does this post set have a valid wiki page representation? - def has_wiki? - raise NotImplementedError - end - - # Should return an array of strings representing the tags. - def tags - raise NotImplementedError - end - - # Given an ActiveRelation object, perform the necessary pagination to - # extract at most elements. Should return an array. - def slice(relation) - raise NotImplementedError - end - - # For cases where we're not relying on the default pagination - # implementation (for example, if the ids are cached in a string) - # then pass in the offset/before_id/after_id parameters here. - def pagination_options - raise NotImplementedError - end - - # This method should throw an exception if for whatever reason the query - # is invalid or forbidden. - def validate - end - - # Clear out any memoized instance variables. - def reload - @posts = nil - @presenter = nil - @tag_string = nil - end - - def tag_string - @tag_string ||= tags.join(" ") - end - - def is_first_page? - raise NotImplementedError - end - - def is_last_page? - posts.size == 0 - end - - def presenter - @presenter ||= PostSetPresenter.new(self) - end - - def limit - Danbooru.config.posts_per_page - end - end -end diff --git a/app/logical/post_sets/error.rb b/app/logical/post_sets/error.rb deleted file mode 100644 index e266775a2..000000000 --- a/app/logical/post_sets/error.rb +++ /dev/null @@ -1,4 +0,0 @@ -module PostSets - class Error < Exception - end -end diff --git a/app/logical/post_sets/favorite.rb b/app/logical/post_sets/favorite.rb deleted file mode 100644 index 02af7d334..000000000 --- a/app/logical/post_sets/favorite.rb +++ /dev/null @@ -1,33 +0,0 @@ -module PostSets - module Favorite - def user - @user ||= ::User.find(params[:id]) - end - - def tags - @tags ||= ["fav:#{user.name}"] - end - - def has_wiki? - false - end - - def reload - super - @user = nil - @count = nil - end - - def count - @count ||= relation.count - end - - def posts - @posts ||= slice(relation).map(&:post) - end - - def relation - ::Favorite.model_for(user.id).where("user_id = ?", user.id).includes(:post).order("id desc") - end - end -end diff --git a/app/logical/post_sets/numbered.rb b/app/logical/post_sets/numbered.rb deleted file mode 100644 index 99398fab6..000000000 --- a/app/logical/post_sets/numbered.rb +++ /dev/null @@ -1,51 +0,0 @@ -module PostSets - module Numbered - def total_pages - @total_pages ||= (count / limit.to_f).ceil.to_i - end - - def reload - super - @total_pages = nil - end - - def slice(relation) - relation.offset(offset).limit(limit).all - end - - def pagination_options - {:offset => offset} - end - - def is_first_page? - offset == 0 - end - - def validate - super - validate_page - end - - def validate_page - if page > 1_000 - raise Error.new("You cannot explicitly specify the page after page 1000") - end - end - - def page - @page ||= params[:page] ? params[:page].to_i : 1 - end - - def total_pages - (count / limit.to_f).ceil - end - - def current_page - page - end - - def offset - ((page < 1) ? 0 : (page - 1)) * limit - end - end -end diff --git a/app/logical/post_sets/pool.rb b/app/logical/post_sets/pool.rb deleted file mode 100644 index 246f4338a..000000000 --- a/app/logical/post_sets/pool.rb +++ /dev/null @@ -1,30 +0,0 @@ -# This only works with the numbered paginator because of the way -# the association is stored. -module PostSets - module Pool - def pool - @pool ||= ::Pool.find(params[:id]) - end - - def tags - ["pool:#{pool.name}"] - end - - def has_wiki? - true - end - - def count - pool.post_count - end - - def posts - @posts ||= pool.posts(pagination_options.merge(:limit => limit)).all - end - - def reload - super - @pool = nil - end - end -end diff --git a/app/logical/post_sets/post.rb b/app/logical/post_sets/post.rb deleted file mode 100644 index 9b8ea25d8..000000000 --- a/app/logical/post_sets/post.rb +++ /dev/null @@ -1,63 +0,0 @@ -module PostSets - module Post - def tag_string - @tag_string ||= params[:tags].to_s.downcase - end - - def count - @count ||= ::Post.fast_count(tag_string) - end - - def posts - @posts ||= slice(::Post.tag_match(tag_string)) - end - - def reload - super - @tag_array = nil - @tag_string = nil - @count = nil - @wiki_page = nil - @artist = nil - end - - def wiki_page - @wiki_page ||= ::WikiPage.titled(tag_string).first - end - - def artist - @artist ||= ::Artist.find_by_name(tag_string) - end - - def has_wiki? - is_single_tag? - end - - def is_single_tag? - tag_array.size == 1 - end - - def tag_array - @tag_array ||= ::Tag.scan_query(tag_string) - end - - def tags - tag_array - end - - def validate - super - validate_query_count - end - - def validate_query_count - if !CurrentUser.is_privileged? && tag_array.size > 2 - raise Error.new("You can only search up to two tags at once with a basic account") - end - - if tag_array.size > 6 - raise Error.new("You can only search up to six tags at once") - end - end - end -end diff --git a/app/logical/post_sets/sequential.rb b/app/logical/post_sets/sequential.rb deleted file mode 100644 index c4b41c74b..000000000 --- a/app/logical/post_sets/sequential.rb +++ /dev/null @@ -1,45 +0,0 @@ -module PostSets - module Sequential - def before_id - params[:before_id] - end - - def after_id - params[:after_id] - end - - def slice(relation) - if before_id - relation.where("id < ?", before_id).order("id desc").limit(limit).all - elsif after_id - relation.where("id > ?", after_id).order("id asc").limit(limit).all.reverse - else - relation.limit(limit).all - end - end - - def first_id - if posts.any? - posts.first.id - else - nil - end - end - - def last_id - if posts.any? - posts.last.id - else - nil - end - end - - def pagination_options - {:before_id => before_id, :after_id => after_id} - end - - def is_first_page? - before_id.nil? - end - end -end diff --git a/app/logical/post_sets/wiki_page.rb b/app/logical/post_sets/wiki_page.rb deleted file mode 100644 index dc48aebfc..000000000 --- a/app/logical/post_sets/wiki_page.rb +++ /dev/null @@ -1,29 +0,0 @@ -module PostSets - module WikiPage - def wiki_page - @wiki_page ||= begin - if params[:id] - ::WikiPage.find(params[:id]) - elsif params[:tags] - ::WikiPage.titled(params[:tags]).first - end - end - end - - def has_wiki? - true - end - - def tags - @tags ||= ::Tag.scan_query(wiki_page.title) - end - - def posts - @posts ||= slice(::Post.tag_match(tag_string)) - end - - def count - @count ||= ::Post.fast_count(tag_string) - end - end -end diff --git a/app/models/post.rb b/app/models/post.rb index 59b686364..32bf8ec8e 100644 --- a/app/models/post.rb +++ b/app/models/post.rb @@ -39,11 +39,23 @@ class Post < ActiveRecord::Base scope :for_user, lambda {|user_id| where(["uploader_string = ?", "uploader:#{user_id}"])} scope :available_for_moderation, lambda {where(["id NOT IN (SELECT pd.post_id FROM post_disapprovals pd WHERE pd.user_id = ?)", CurrentUser.id])} scope :hidden_from_moderation, lambda {where(["id IN (SELECT pd.post_id FROM post_disapprovals pd WHERE pd.user_id = ?)", CurrentUser.id])} - scope :before_id, lambda {|id| id.present? ? where(["posts.id < ?", id]) : where("TRUE")} - scope :after_id, lambda {|id| id.present? ? where("posts.id > ?", id) : where("true")} scope :tag_match, lambda {|query| Post.tag_match_helper(query)} search_methods :tag_match - + scope :after_id, Proc.new {|num| + if num.present? + where("id > ?", num.to_i).reorder("id asc") + else + where("true") + end + } + scope :before_id, Proc.new {|num| + if num.present? + where("id < ?", num.to_i).reorder("id desc") + else + where("true") + end + } + module FileMethods def delete_files FileUtils.rm_f(file_path) diff --git a/app/presenters/post_set_presenter.rb b/app/presenters/post_set_presenter.rb index f60629c4d..7afcd572f 100644 --- a/app/presenters/post_set_presenter.rb +++ b/app/presenters/post_set_presenter.rb @@ -1,17 +1,13 @@ require 'pp' class PostSetPresenter < Presenter - attr_accessor :post_set, :tag_set_presenter + attr_accessor :posts, :tag_set_presenter - def initialize(post_set) - @post_set = post_set + def initialize(posts) + @posts = posts @tag_set_presenter = TagSetPresenter.new(RelatedTagCalculator.calculate_from_sample_to_array(@post_set.tags).map {|x| x[0]}) end - def posts - post_set.posts - end - def tag_list_html(template) tag_set_presenter.tag_list_html(template) end diff --git a/app/views/post_versions/index.html.erb b/app/views/post_versions/index.html.erb index d3686b146..6ee81932c 100644 --- a/app/views/post_versions/index.html.erb +++ b/app/views/post_versions/index.html.erb @@ -1,81 +1,57 @@ -
    -
    -
    -
    - -
    -
    - <%= form_tag(post_versions_path, :method => :get) do %> - <%= text_field_tag "user_name", params[:user_name], :id => "user_name", :size => 20 %> <%= submit_tag "Search" %> - <% end %> -
    +
    +
    + -
    -
    - -
    -
    - <%= form_tag(post_versions_path, :method => :get) do %> - <%= text_field_tag "post_id", params[:post_id], :id => "post_id", :size => 10 %> <%= submit_tag "Search" %> - <% end %> -
    -
    -
    -
    - - - - - - - - - - - - - - - - - - - - <% @change_list.each do |change| %> - - - - - - - - - + +
    +
    PostDateUserRatingParentIP AddressTags
    - <%= button_to_function "Undo", "PostTagHistory.undo()", :id => "undo" %> - <%= button_to_function "Revert to", "PostTagHistory.revert()", :id => "revert" %> -
    <%= link_to change[:change].post_id, :controller => "post", :action => "show", :id => change[:change].post_id %><%= change[:change].created_at.strftime("%Y-%m-%d %H:%M") %><%= link_to change[:change].author, :controller => "user", :action => "show", :id => change[:change].user_id %><%= change[:change].rating %><%= change[:parent_id] %> - <% if @current_user.is_admin? %> - <%= change[:ip_addr] %> - <% end %> - - <%= tag_list(change[:added_tags], :obsolete => change[:obsolete_added_tags], :prefix => "+") %> - <%= tag_list(change[:removed_tags], :obsolete=>change[:obsolete_removed_tags], :prefix=>"-") %> - <%= tag_list(change[:unchanged_tags], :prefix => "") %> -
    + + + + + + + + + - <% end %> - -
    PostDateUserRatingParentIP AddressTags
    + + + <% @post_versions.each do |post_version| %> + + <%= link_to(post_version.post_id, post_path(post_version.post_id)) %> + <%= post_version.updated_at.strftime("%Y-%m-%d %H:%M") %> + <%= link_to(post_version.updater.name, user_path(post_version.updater_id)) %> + <%= post_version.rating %> + <%= post_version.parent_id %> + + <% if CurrentUser.is_admin? %> + <%= post_version.updater_ip_addr %> + <% end %> + + + <% post_version.add_tag_array.each do |tag| %> + <%= tag %> + <% end %> + + <% post_version.del_tag_array.each do |tag| %> + <%= tag %> + <% end %> + + + <% end %> + + +
    + +
    + <%= sequential_paginator(@post_versions) %> +
    - - -
    - <%= tag_history_pagination_links(@changes) %> -
    diff --git a/config/initializers/lib.rb b/config/initializers/lib.rb new file mode 100644 index 000000000..cb1b75778 --- /dev/null +++ b/config/initializers/lib.rb @@ -0,0 +1 @@ +require 'danbooru/paginator' \ No newline at end of file diff --git a/lib/danbooru/paginator.rb b/lib/danbooru/paginator.rb new file mode 100644 index 000000000..bed83b368 --- /dev/null +++ b/lib/danbooru/paginator.rb @@ -0,0 +1,6 @@ +require "danbooru/paginator/active_record_extension" +require "danbooru/paginator/collection_extension" +require "danbooru/paginator/numbered_collection_extension" +require "danbooru/paginator/sequential_collection_extension" + +ActiveRecord::Base.__send__(:include, Danbooru::Paginator::ActiveRecordExtension) diff --git a/lib/danbooru/paginator/active_record_extension.rb b/lib/danbooru/paginator/active_record_extension.rb new file mode 100644 index 000000000..6302ef253 --- /dev/null +++ b/lib/danbooru/paginator/active_record_extension.rb @@ -0,0 +1,68 @@ +require 'active_support/concern' + +module Danbooru + module Paginator + module ActiveRecordExtension + extend ActiveSupport::Concern + + module ClassMethods + def paginate(page) + if use_sequential_paginator?(page) + paginate_sequential(page) + else + paginate_numbered(page) + end + end + + def use_sequential_paginator?(page) + page =~ /[ab]\d+/i + end + + def paginate_sequential(page) + if page =~ /b(\d+)/ + paginate_sequential_before($1) + elsif page =~ /a(\d+)/ + paginate_sequential_after($1) + else + paginate_numbered(page) + end + end + + def paginate_sequential_before(before_id) + limit(records_per_page).where("id < ?", before_id.to_i).reorder("id desc").tap do |obj| + obj.extend(SequentialCollectionExtension) + obj.sequential_paginator_mode = :before + end + end + + def paginate_sequential_after(after_id) + limit(records_per_page).where("id > ?", after_id.to_i).reorder("id asc").tap do |obj| + obj.extend(SequentialCollectionExtension) + obj.sequential_paginator_mode = :after + end + end + + def paginate_numbered(page) + page = [page.to_i, 1].max + limit(records_per_page).offset((page - 1) * records_per_page).tap do |obj| + obj.extend(NumberedCollectionExtension) + obj.total_pages = (obj.total_count / records_per_page.to_f).ceil + obj.current_page = page + end + end + + def records_per_page + Danbooru.config.posts_per_page + end + + # taken from kaminari (https://github.com/amatsuda/kaminari) + def total_count + c = except(:offset, :limit, :order) + c = c.reorder(nil) + c = c.count + c.respond_to?(:count) ? c.count : c + end + end + end + end +end diff --git a/lib/danbooru/paginator/collection_extension.rb b/lib/danbooru/paginator/collection_extension.rb new file mode 100644 index 000000000..d15a53c10 --- /dev/null +++ b/lib/danbooru/paginator/collection_extension.rb @@ -0,0 +1,6 @@ +module Danbooru + module Paginator + module CollectionExtension + end + end +end diff --git a/lib/danbooru/paginator/numbered_collection_extension.rb b/lib/danbooru/paginator/numbered_collection_extension.rb new file mode 100644 index 000000000..644807625 --- /dev/null +++ b/lib/danbooru/paginator/numbered_collection_extension.rb @@ -0,0 +1,27 @@ +module Danbooru + module Paginator + module NumberedCollectionExtension + attr_accessor :current_page, :total_pages + + def self.extended(obj) + obj.extend(Danbooru::Paginator::CollectionExtension) + end + + def is_first_page? + current_page == 1 + end + + def is_last_page? + current_page == total_pages + end + + def is_sequential_paginator? + false + end + + def is_numbered_paginator? + true + end + end + end +end diff --git a/lib/danbooru/paginator/sequential_collection_extension.rb b/lib/danbooru/paginator/sequential_collection_extension.rb new file mode 100644 index 000000000..ba45be58f --- /dev/null +++ b/lib/danbooru/paginator/sequential_collection_extension.rb @@ -0,0 +1,51 @@ +module Danbooru + module Paginator + module SequentialCollectionExtension + attr_accessor :sequential_paginator_mode + + def self.extended(obj) + obj.extend(Danbooru::Paginator::CollectionExtension) + end + + def is_first_page? + size == 0 + end + + def is_last_page? + size == 0 + end + + def is_sequential_paginator? + true + end + + def is_numbered_paginator? + false + end + + def to_a + if sequential_paginator_mode == :before + super + else + super.reverse + end + end + + def before_id + if size > 0 + self[-1].id + else + nil + end + end + + def after_id + if size > 0 + self[0].id + else + nil + end + end + end + end +end