allow pagination by min_id and max_id (#14776)

* allow pagination by min_id and max_id

* also AccountConversation allows min_id,max_id pair

* also home,list TL allows min_id,max_id pair
pull/14780/head
tateisu 2020-09-13 00:09:49 +09:00 committed by GitHub
parent 4e4b3a0c8e
commit fa0c71f0d9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 8 additions and 6 deletions

View File

@ -38,15 +38,16 @@ class AccountConversation < ApplicationRecord
class << self class << self
def to_a_paginated_by_id(limit, options = {}) def to_a_paginated_by_id(limit, options = {})
if options[:min_id] if options[:min_id]
paginate_by_min_id(limit, options[:min_id]).reverse paginate_by_min_id(limit, options[:min_id], options[:max_id]).reverse
else else
paginate_by_max_id(limit, options[:max_id], options[:since_id]).to_a paginate_by_max_id(limit, options[:max_id], options[:since_id]).to_a
end end
end end
def paginate_by_min_id(limit, min_id = nil) def paginate_by_min_id(limit, min_id = nil, max_id = nil)
query = order(arel_table[:last_status_id].asc).limit(limit) query = order(arel_table[:last_status_id].asc).limit(limit)
query = query.where(arel_table[:last_status_id].gt(min_id)) if min_id.present? query = query.where(arel_table[:last_status_id].gt(min_id)) if min_id.present?
query = query.where(arel_table[:last_status_id].lt(max_id)) if max_id.present?
query query
end end

View File

@ -14,15 +14,16 @@ module Paginable
# Differs from :paginate_by_max_id in that it gives the results immediately following min_id, # Differs from :paginate_by_max_id in that it gives the results immediately following min_id,
# whereas since_id gives the items with largest id, but with since_id as a cutoff. # whereas since_id gives the items with largest id, but with since_id as a cutoff.
# Results will be in ascending order by id. # Results will be in ascending order by id.
scope :paginate_by_min_id, ->(limit, min_id = nil) { scope :paginate_by_min_id, ->(limit, min_id = nil, max_id = nil) {
query = reorder(arel_table[:id]).limit(limit) query = reorder(arel_table[:id]).limit(limit)
query = query.where(arel_table[:id].gt(min_id)) if min_id.present? query = query.where(arel_table[:id].gt(min_id)) if min_id.present?
query = query.where(arel_table[:id].lt(max_id)) if max_id.present?
query query
} }
def self.to_a_paginated_by_id(limit, options = {}) def self.to_a_paginated_by_id(limit, options = {})
if options[:min_id].present? if options[:min_id].present?
paginate_by_min_id(limit, options[:min_id]).reverse paginate_by_min_id(limit, options[:min_id], options[:max_id]).reverse
else else
paginate_by_max_id(limit, options[:max_id], options[:since_id]).to_a paginate_by_max_id(limit, options[:max_id], options[:since_id]).to_a
end end

View File

@ -20,12 +20,12 @@ class Feed
protected protected
def from_redis(limit, max_id, since_id, min_id) def from_redis(limit, max_id, since_id, min_id)
max_id = '+inf' if max_id.blank?
if min_id.blank? if min_id.blank?
max_id = '+inf' if max_id.blank?
since_id = '-inf' if since_id.blank? since_id = '-inf' if since_id.blank?
unhydrated = redis.zrevrangebyscore(key, "(#{max_id}", "(#{since_id}", limit: [0, limit], with_scores: true).map(&:first).map(&:to_i) unhydrated = redis.zrevrangebyscore(key, "(#{max_id}", "(#{since_id}", limit: [0, limit], with_scores: true).map(&:first).map(&:to_i)
else else
unhydrated = redis.zrangebyscore(key, "(#{min_id}", '+inf', limit: [0, limit], with_scores: true).map(&:first).map(&:to_i) unhydrated = redis.zrangebyscore(key, "(#{min_id}", "(#{max_id}", limit: [0, limit], with_scores: true).map(&:first).map(&:to_i)
end end
Status.where(id: unhydrated).cache_ids Status.where(id: unhydrated).cache_ids