FIX: `/t/:topic_id/last` route did not return any posts.

This commit is contained in:
Guo Xiang Tan 2018-07-13 14:25:12 +08:00
parent c2cfb6ebae
commit c722b07057
2 changed files with 41 additions and 12 deletions

View File

@ -248,20 +248,21 @@ class TopicView
def filter_posts_near(post_number) def filter_posts_near(post_number)
posts_before = (@limit.to_f / 4).floor posts_before = (@limit.to_f / 4).floor
posts_before = 1 if posts_before.zero? posts_before = 1 if posts_before.zero?
sort_order = get_sort_order(post_number)
before_post_ids = @filtered_posts.order(sort_order: :desc) before_post_ids = @filtered_posts.order(sort_order: :desc)
.where("posts.sort_order < #{sort_order_sql(post_number)}",) .where("posts.sort_order < ?", sort_order)
.limit(posts_before) .limit(posts_before)
.pluck(:id) .pluck(:id)
post_ids = before_post_ids + @filtered_posts.order(sort_order: :asc) post_ids = before_post_ids + @filtered_posts.order(sort_order: :asc)
.where("posts.sort_order >= #{sort_order_sql(post_number)}") .where("posts.sort_order >= ?", sort_order)
.limit(@limit - before_post_ids.length) .limit(@limit - before_post_ids.length)
.pluck(:id) .pluck(:id)
if post_ids.length < @limit if post_ids.length < @limit
post_ids = post_ids + @filtered_posts.order(sort_order: :desc) post_ids = post_ids + @filtered_posts.order(sort_order: :desc)
.where("posts.sort_order < #{sort_order_sql(post_number)}") .where("posts.sort_order < ?", sort_order)
.offset(before_post_ids.length) .offset(before_post_ids.length)
.limit(@limit - post_ids.length) .limit(@limit - post_ids.length)
.pluck(:id) .pluck(:id)
@ -483,16 +484,30 @@ class TopicView
private private
def sort_order_sql(post_number) def get_sort_order(post_number)
<<~SQL sql = <<~SQL
(
SELECT posts.sort_order SELECT posts.sort_order
FROM posts FROM posts
WHERE posts.post_number = #{post_number.to_i} WHERE posts.post_number = #{post_number.to_i}
AND posts.topic_id = #{@topic.id.to_i} AND posts.topic_id = #{@topic.id.to_i}
LIMIT 1 LIMIT 1
)
SQL SQL
sort_order = DB.query_single(sql).first
if !sort_order
sql = <<~SQL
SELECT posts.sort_order
FROM posts
WHERE posts.topic_id = #{@topic.id.to_i}
ORDER BY @(post_number - #{post_number.to_i})
LIMIT 1
SQL
sort_order = DB.query_single(sql).first
end
sort_order
end end
def filter_post_types(posts) def filter_post_types(posts)
@ -506,14 +521,16 @@ class TopicView
end end
def filter_posts_by_post_number(post_number, asc) def filter_posts_by_post_number(post_number, asc)
sort_order = get_sort_order(post_number)
posts = posts =
if asc if asc
@filtered_posts @filtered_posts
.where("sort_order > #{sort_order_sql(post_number)}") .where("sort_order > ?", sort_order)
.order(sort_order: :asc) .order(sort_order: :asc)
else else
@filtered_posts @filtered_posts
.where("sort_order < #{sort_order_sql(post_number)}") .where("sort_order < ?", sort_order)
.order(sort_order: :desc) .order(sort_order: :desc)
end end

View File

@ -458,6 +458,18 @@ describe TopicView do
expect(near_view.contains_gaps?).to eq(false) expect(near_view.contains_gaps?).to eq(false)
end end
describe 'when post_number is too large' do
it "snaps to the lower boundary" do
near_view = TopicView.new(topic.id, evil_trout,
post_number: 99999999,
)
expect(near_view.desired_post).to eq(p2)
expect(near_view.posts).to eq([p2, p3, p5])
expect(near_view.contains_gaps?).to eq(false)
end
end
it "gaps deleted posts to an admin" do it "gaps deleted posts to an admin" do
evil_trout.admin = true evil_trout.admin = true
near_view = topic_view_near(p3) near_view = topic_view_near(p3)