class Recurly::Pager

Attributes

client[RW]
data[R]
next[R]

Public Class Methods

new(client:, path:, options: {}) click to toggle source
# File lib/recurly/pager.rb, line 6
def initialize(client:, path:, options: {})
  @client = client
  @path = path
  @options = options
  rewind!
end

Public Instance Methods

count() click to toggle source

Makes a HEAD request to the API to determine how many total records exist.

# File lib/recurly/pager.rb, line 26
def count
  resource = @client.send(:head, self.next, **@options)
  resource.get_response.total_records
end
each(&block) click to toggle source

Enumerates each item on the server. Each item is yielded to the block presenting the effect of a continuous stream of items. In reality, the pager is fetching blocks of data (pages) under the hood. This method yields a given block with the next item to process.

@example

plans = client.list_plans()
plans.each do |plan|
  puts "Plan: #{plan.id}"
end

@example

plans = client.list_plans()
plans.each.each_with_index do |plan, idx|
  puts "Plan #{idx}: #{plan.id}"
end
# File lib/recurly/pager.rb, line 74
def each(&block)
  if block_given?
    item_enumerator.each(&block)
  else
    item_enumerator
  end
end
each_page(&block) click to toggle source

Enumerates each “page” from the server. This method yields a given block with the array of items in the page ‘data` and the page number the pagination is on `page_num` which is 0-indexed.

@example

plans = client.list_plans()
plans.each_page do |data|
  data.each do |plan|
    puts "Plan: #{plan.id}"
  end
end

@example

plans = client.list_plans()
plans.each_page.each_with_index do |data, page_num|
  puts "Page Number: #{page_num}"
  data.each do |plan|
    puts "Plan: #{plan.id}"
  end
end
# File lib/recurly/pager.rb, line 51
def each_page(&block)
  if block_given?
    page_enumerator.each(&block)
  else
    page_enumerator
  end
end
first() click to toggle source

Performs a request with the pager ‘limit` set to 1 and only returns the first result in the response.

# File lib/recurly/pager.rb, line 15
def first
  # Modify the @next url to set the :limit to 1
  original_next = @next
  @next = @path
  fetch_next!(@options.merge(params: @options.fetch(:params, {}).merge({ limit: 1 })))
  # Restore the @next url to the original
  @next = original_next
  @data.first
end
has_more?() click to toggle source
# File lib/recurly/pager.rb, line 82
def has_more?
  !!@has_more
end
requires_client?() click to toggle source
# File lib/recurly/pager.rb, line 86
def requires_client?
  true
end

Private Instance Methods

extract_path(uri_or_path) click to toggle source

Returns just the path and parameters so we can safely reuse the connection

# File lib/recurly/pager.rb, line 131
def extract_path(uri_or_path)
  uri = URI(uri_or_path)
  uri.kind_of?(URI::HTTP) ? uri.request_uri : uri_or_path
end
fetch_next!(options) click to toggle source
# File lib/recurly/pager.rb, line 117
def fetch_next!(options)
  path = extract_path(self.next)
  page = @client.send(:get, path, **options)
  @data = page.data.map { |d| JSONParser.from_json(d) }
  @has_more = page.has_more
  @next = page.next
end
item_enumerator() click to toggle source
# File lib/recurly/pager.rb, line 92
def item_enumerator
  Enumerator.new do |yielder|
    page_enumerator.each do |data|
      data.each do |item|
        yielder << item
      end
    end
  end
end
page_enumerator() click to toggle source
# File lib/recurly/pager.rb, line 102
def page_enumerator
  Enumerator.new do |yielder|
    loop do
      # Pass in @options when requesting the first page (@data.empty?)
      next_options = @data.empty? ? @options : @options.merge(params: {})
      fetch_next!(next_options)
      yielder << data
      unless has_more?
        rewind!
        break
      end
    end
  end
end
rewind!() click to toggle source
# File lib/recurly/pager.rb, line 125
def rewind!
  @data = []
  @next = @path
end