API pagination for all collections using Link header

This commit is contained in:
Eugen Rochko
2016-11-09 17:48:44 +01:00
parent 8d7fc5da6c
commit b13e7dda1f
13 changed files with 123 additions and 63 deletions

View File

@ -133,36 +133,38 @@ class Account < ApplicationRecord
[]
end
def self.find_local!(username)
find_remote!(username, nil)
end
class << self
def find_local!(username)
find_remote!(username, nil)
end
def self.find_remote!(username, domain)
where(arel_table[:username].matches(username)).where(domain.nil? ? { domain: nil } : arel_table[:domain].matches(domain)).take!
end
def find_remote!(username, domain)
where(arel_table[:username].matches(username)).where(domain.nil? ? { domain: nil } : arel_table[:domain].matches(domain)).take!
end
def self.find_local(username)
find_local!(username)
rescue ActiveRecord::RecordNotFound
nil
end
def find_local(username)
find_local!(username)
rescue ActiveRecord::RecordNotFound
nil
end
def self.find_remote(username, domain)
find_remote!(username, domain)
rescue ActiveRecord::RecordNotFound
nil
end
def find_remote(username, domain)
find_remote!(username, domain)
rescue ActiveRecord::RecordNotFound
nil
end
def self.following_map(target_account_ids, account_id)
Follow.where(target_account_id: target_account_ids).where(account_id: account_id).map { |f| [f.target_account_id, true] }.to_h
end
def following_map(target_account_ids, account_id)
Follow.where(target_account_id: target_account_ids).where(account_id: account_id).map { |f| [f.target_account_id, true] }.to_h
end
def self.followed_by_map(target_account_ids, account_id)
Follow.where(account_id: target_account_ids).where(target_account_id: account_id).map { |f| [f.account_id, true] }.to_h
end
def followed_by_map(target_account_ids, account_id)
Follow.where(account_id: target_account_ids).where(target_account_id: account_id).map { |f| [f.account_id, true] }.to_h
end
def self.blocking_map(target_account_ids, account_id)
Block.where(target_account_id: target_account_ids).where(account_id: account_id).map { |b| [b.target_account_id, true] }.to_h
def blocking_map(target_account_ids, account_id)
Block.where(target_account_id: target_account_ids).where(account_id: account_id).map { |b| [b.target_account_id, true] }.to_h
end
end
before_create do

View File

@ -2,11 +2,11 @@ module Paginable
extend ActiveSupport::Concern
included do
def self.paginate_by_max_id(limit, max_id = nil, since_id = nil)
query = order('id desc').limit(limit)
scope :paginate_by_max_id, -> (limit, max_id = nil, since_id = nil) {
query = order(arel_table[:id].desc).limit(limit)
query = query.where(arel_table[:id].lt(max_id)) unless max_id.blank?
query = query.where(arel_table[:id].gt(since_id)) unless since_id.blank?
query
end
}
end
end

View File

@ -1,4 +1,5 @@
class Favourite < ApplicationRecord
include Paginable
include Streamable
belongs_to :account, inverse_of: :favourites

View File

@ -12,11 +12,13 @@ class Feed
# If we're after most recent items and none are there, we need to precompute the feed
if unhydrated.empty? && max_id == '+inf' && since_id == '-inf'
RegenerationWorker.perform_async(@account.id, @type)
Status.send("as_#{@type}_timeline", @account).paginate_by_max_id(limit, nil, nil)
@statuses = Status.send("as_#{@type}_timeline", @account).paginate_by_max_id(limit, nil, nil)
else
status_map = Status.where(id: unhydrated).with_includes.with_counters.map { |status| [status.id, status] }.to_h
unhydrated.map { |id| status_map[id] }.compact
@statuses = unhydrated.map { |id| status_map[id] }.compact
end
@statuses
end
private

View File

@ -1,4 +1,5 @@
class Follow < ApplicationRecord
include Paginable
include Streamable
belongs_to :account

View File

@ -78,14 +78,6 @@ class Status < ApplicationRecord
ids.map { |id| statuses[id].first }
end
def reblogged_by(limit)
Account.where(id: reblogs.limit(limit).pluck(:account_id)).with_counters
end
def favourited_by(limit)
Account.where(id: favourites.limit(limit).pluck(:account_id)).with_counters
end
class << self
def as_home_timeline(account)
where(account: [account] + account.following).with_includes.with_counters