From c722b07057561fd6130d2c7d2afd021cfe846194 Mon Sep 17 00:00:00 2001 From: Guo Xiang Tan Date: Fri, 13 Jul 2018 14:25:12 +0800 Subject: [PATCH] FIX: `/t/:topic_id/last` route did not return any posts. --- lib/topic_view.rb | 41 +++++++++++++++++++++--------- spec/components/topic_view_spec.rb | 12 +++++++++ 2 files changed, 41 insertions(+), 12 deletions(-) diff --git a/lib/topic_view.rb b/lib/topic_view.rb index e093ea865c2..f2c5e51894d 100644 --- a/lib/topic_view.rb +++ b/lib/topic_view.rb @@ -248,20 +248,21 @@ class TopicView def filter_posts_near(post_number) posts_before = (@limit.to_f / 4).floor posts_before = 1 if posts_before.zero? + sort_order = get_sort_order(post_number) 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) .pluck(:id) 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) .pluck(:id) if post_ids.length < @limit 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) .limit(@limit - post_ids.length) .pluck(:id) @@ -483,16 +484,30 @@ class TopicView private - def sort_order_sql(post_number) - <<~SQL - ( + def get_sort_order(post_number) + sql = <<~SQL + SELECT posts.sort_order + FROM posts + WHERE posts.post_number = #{post_number.to_i} + AND posts.topic_id = #{@topic.id.to_i} + LIMIT 1 + SQL + + sort_order = DB.query_single(sql).first + + if !sort_order + sql = <<~SQL SELECT posts.sort_order FROM posts - WHERE posts.post_number = #{post_number.to_i} - AND posts.topic_id = #{@topic.id.to_i} + WHERE posts.topic_id = #{@topic.id.to_i} + ORDER BY @(post_number - #{post_number.to_i}) LIMIT 1 - ) - SQL + SQL + + sort_order = DB.query_single(sql).first + end + + sort_order end def filter_post_types(posts) @@ -506,14 +521,16 @@ class TopicView end def filter_posts_by_post_number(post_number, asc) + sort_order = get_sort_order(post_number) + posts = if asc @filtered_posts - .where("sort_order > #{sort_order_sql(post_number)}") + .where("sort_order > ?", sort_order) .order(sort_order: :asc) else @filtered_posts - .where("sort_order < #{sort_order_sql(post_number)}") + .where("sort_order < ?", sort_order) .order(sort_order: :desc) end diff --git a/spec/components/topic_view_spec.rb b/spec/components/topic_view_spec.rb index 8f5fdbc6872..05fd50db590 100644 --- a/spec/components/topic_view_spec.rb +++ b/spec/components/topic_view_spec.rb @@ -458,6 +458,18 @@ describe TopicView do expect(near_view.contains_gaps?).to eq(false) 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 evil_trout.admin = true near_view = topic_view_near(p3)