Improve sequential paginator

fixes #2044, fixes #1298
This commit is contained in:
Toks
2013-12-04 14:41:50 -05:00
parent 067d15d754
commit 9585e32914
4 changed files with 80 additions and 10 deletions

View File

@@ -3,11 +3,13 @@ module PaginationHelper
html = '<div class="paginator"><menu>' html = '<div class="paginator"><menu>'
if records.any? if records.any?
if params[:page] =~ /[ab]/ if params[:page] =~ /[ab]/ && !records.is_first_page?
html << '<li>' + link_to("< Previous", params.merge(:page => "a#{records[0].id}"), :rel => "prev") + '</li>' html << '<li>' + link_to("< Previous", params.merge(:page => "a#{records[0].id}"), :rel => "prev") + '</li>'
end end
html << '<li>' + link_to("Next >", params.merge(:page => "b#{records[-1].id}"), :rel => "next") + '</li>' unless records.is_last_page?
html << '<li>' + link_to("Next >", params.merge(:page => "b#{records[-1].id}"), :rel => "next") + '</li>'
end
end end
html << "</menu></div>" html << "</menu></div>"

View File

@@ -31,7 +31,7 @@ module Danbooru
end end
def paginate_sequential_before(before_id = nil) def paginate_sequential_before(before_id = nil)
c = limit(records_per_page) c = limit(records_per_page + 1)
if before_id.to_i > 0 if before_id.to_i > 0
c = c.where("#{table_name}.id < ?", before_id.to_i) c = c.where("#{table_name}.id < ?", before_id.to_i)
@@ -44,7 +44,7 @@ module Danbooru
end end
def paginate_sequential_after(after_id) def paginate_sequential_after(after_id)
limit(records_per_page).where("#{table_name}.id > ?", after_id.to_i).reorder("#{table_name}.id asc").tap do |obj| limit(records_per_page + 1).where("#{table_name}.id > ?", after_id.to_i).reorder("#{table_name}.id asc").tap do |obj|
obj.extend(SequentialCollectionExtension) obj.extend(SequentialCollectionExtension)
obj.sequential_paginator_mode = :after obj.sequential_paginator_mode = :after
end end

View File

@@ -4,18 +4,26 @@ module Danbooru
attr_accessor :sequential_paginator_mode attr_accessor :sequential_paginator_mode
def is_first_page? def is_first_page?
size == 0 if sequential_paginator_mode == :before
false
else
size <= records_per_page
end
end end
def is_last_page? def is_last_page?
size == 0 if sequential_paginator_mode == :after
false
else
size <= records_per_page
end
end end
def to_a def to_a
if sequential_paginator_mode == :before if sequential_paginator_mode == :before
super super.first(records_per_page)
else else
super.reverse super.first(records_per_page).reverse
end end
end end
end end

View File

@@ -34,10 +34,15 @@ module PostSets
assert_equal(1, @set.posts.size) assert_equal(1, @set.posts.size)
assert_equal(@post_1.id, @set.posts.first.id) assert_equal(@post_1.id, @set.posts.first.id)
end end
should "know what page it's on" do
refute(@set.favorites.is_first_page?)
refute(@set.favorites.is_last_page?)
end
end end
end end
context "a favorite set for after the second most recent post" do context "a favorite set for after the third most recent post" do
setup do setup do
id = ::Favorite.where(:user_id => @user.id, :post_id => @post_2.id).first.id id = ::Favorite.where(:user_id => @user.id, :post_id => @post_2.id).first.id
::Favorite.stubs(:records_per_page).returns(1) ::Favorite.stubs(:records_per_page).returns(1)
@@ -45,10 +50,55 @@ module PostSets
end end
context "a sequential paginator" do context "a sequential paginator" do
should "return the most recent element" do should "return the second most recent element" do
assert_equal(1, @set.posts.size) assert_equal(1, @set.posts.size)
assert_equal(@post_1.id, @set.posts.first.id) assert_equal(@post_1.id, @set.posts.first.id)
end end
should "know what page it's on" do
refute(@set.favorites.is_first_page?)
refute(@set.favorites.is_last_page?)
end
end
end
context "a favorite set for before the second most recent post" do
setup do
id = ::Favorite.where(:user_id => @user.id, :post_id => @post_1.id).first.id
::Favorite.stubs(:records_per_page).returns(1)
@set = PostSets::Favorite.new(@user.id, "b#{id}")
end
context "a sequential paginator" do
should "return the third most recent element" do
assert_equal(1, @set.posts.size)
assert_equal(@post_2.id, @set.posts.first.id)
end
should "know what page it's on" do
refute(@set.favorites.is_first_page?)
assert(@set.favorites.is_last_page?)
end
end
end
context "a favorite set for after the second most recent post" do
setup do
id = ::Favorite.where(:user_id => @user.id, :post_id => @post_1.id).first.id
::Favorite.stubs(:records_per_page).returns(1)
@set = PostSets::Favorite.new(@user.id, "a#{id}")
end
context "a sequential paginator" do
should "return the most recent element" do
assert_equal(1, @set.posts.size)
assert_equal(@post_3.id, @set.posts.first.id)
end
should "know what page it's on" do
assert(@set.favorites.is_first_page?)
refute(@set.favorites.is_last_page?)
end
end end
end end
@@ -63,6 +113,11 @@ module PostSets
assert_equal(1, @set.posts.size) assert_equal(1, @set.posts.size)
assert_equal(@post_1.id, @set.posts.first.id) assert_equal(@post_1.id, @set.posts.first.id)
end end
should "know what page it's on" do
refute(@set.favorites.is_first_page?)
refute(@set.favorites.is_last_page?)
end
end end
end end
@@ -76,6 +131,11 @@ module PostSets
assert_equal(1, @set.posts.size) assert_equal(1, @set.posts.size)
assert_equal(@post_3.id, @set.posts.first.id) assert_equal(@post_3.id, @set.posts.first.id)
end end
should "know what page it's on" do
assert(@set.favorites.is_first_page?)
refute(@set.favorites.is_last_page?)
end
end end
end end
end end