Class: Forem::ListObject

Inherits:
Object
  • Object
show all
Includes:
Enumerable
Defined in:
lib/forem/list_object.rb

Overview

Wraps a paginated list of API resources returned by collection endpoints.

ListObject implements Enumerable so the current page's items can be iterated with the standard Ruby collection methods. Use #auto_paging_each to transparently iterate across all pages without managing pagination manually.

Two paging modes are supported:

  • page-based (default) — uses +page+/+per_page+ query params. Created by APIOperations::List#list and the paginated_list helper on APIResource.
  • cursor-based — uses an +after+-style cursor (e.g. survey poll endpoints). Created by the cursor_list helper on APIResource.

In both modes the public surface is the same: #data, #has_more?, #each, #next_page, #auto_paging_each.

Examples:

Iterating the current page

articles = client.articles.list(per_page: 5)
articles.each { |a| puts a.title }

Iterating all pages automatically

client.articles.list(per_page: 30).auto_paging_each do |article|
  puts article.title
end

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(data:, per_page:, resource_class:, filters:, requestor:, current_page: nil, fetcher: nil) ⇒ ListObject

Create a new ListObject.

Parameters:

  • data (Array<ForemObject>)

    the resource objects for this page.

  • per_page (Integer)

    the page size requested.

  • resource_class (Class)

    the resource class for this collection.

  • filters (Hash)

    the non-pagination query parameters.

  • requestor (APIRequestor, nil)

    the requestor used to fetch the current page; reused for subsequent pages.

  • current_page (Integer, nil) (defaults to: nil)

    the 1-based current page number, or nil for cursor-based pagination.

  • fetcher (Proc, nil) (defaults to: nil)

    optional callable invoked with (direction, current_list, extra_params) to fetch the next or previous page. Used by custom-path or cursor-based endpoints. When nil, page-based pagination falls back to resource_class.list(...).



69
70
71
72
73
74
75
76
77
# File 'lib/forem/list_object.rb', line 69

def initialize(data:, per_page:, resource_class:, filters:, requestor:, current_page: nil, fetcher: nil)
  @data = data
  @current_page = current_page
  @per_page = per_page
  @resource_class = resource_class
  @filters = filters
  @requestor = requestor
  @fetcher = fetcher
end

Instance Attribute Details

#current_pageInteger? (readonly)

Returns the 1-based current page number for page-based pagination, or nil for cursor-based pagination.

Returns:

  • (Integer, nil)

    the 1-based current page number for page-based pagination, or nil for cursor-based pagination.



36
37
38
# File 'lib/forem/list_object.rb', line 36

def current_page
  @current_page
end

#dataArray<ForemObject> (readonly)

Returns the resource objects on the current page.

Returns:

  • (Array<ForemObject>)

    the resource objects on the current page.



32
33
34
# File 'lib/forem/list_object.rb', line 32

def data
  @data
end

#filtersHash (readonly)

Returns the non-pagination filter parameters used to build this list (e.g. { tag: "ruby" }). These are forwarded when fetching subsequent pages.

Returns:

  • (Hash)

    the non-pagination filter parameters used to build this list (e.g. { tag: "ruby" }). These are forwarded when fetching subsequent pages.



44
45
46
# File 'lib/forem/list_object.rb', line 44

def filters
  @filters
end

#per_pageInteger (readonly)

Returns the maximum number of items per page requested.

Returns:

  • (Integer)

    the maximum number of items per page requested.



39
40
41
# File 'lib/forem/list_object.rb', line 39

def per_page
  @per_page
end

#requestorAPIRequestor? (readonly)

Returns the requestor that produced this list and that will be re-used for fetching additional pages.

Returns:

  • (APIRequestor, nil)

    the requestor that produced this list and that will be re-used for fetching additional pages.



51
52
53
# File 'lib/forem/list_object.rb', line 51

def requestor
  @requestor
end

#resource_classClass (readonly)

Returns the resource class used to construct items.

Returns:

  • (Class)

    the resource class used to construct items.



47
48
49
# File 'lib/forem/list_object.rb', line 47

def resource_class
  @resource_class
end

Instance Method Details

#[](idx) ⇒ ForemObject?

Indexed access to the underlying page data.

Parameters:

  • idx (Integer)

    zero-based item index within the current page.

Returns:



100
101
102
# File 'lib/forem/list_object.rb', line 100

def [](idx)
  @data[idx]
end

#auto_paging_each {|ForemObject| ... } ⇒ void

This method returns an undefined value.

Iterate over every resource across all pages, automatically fetching subsequent pages as needed. Stops when #has_more? is false or #next_page returns nil.

Yields:

  • (ForemObject)

    each resource object across all pages.



121
122
123
124
125
126
127
128
129
# File 'lib/forem/list_object.rb', line 121

def auto_paging_each(&block)
  page = self
  loop do
    page.each(&block)
    break unless page.has_more?
    page = page.next_page
    break unless page
  end
end

#each {|ForemObject| ... } ⇒ Enumerator

Iterate over the resource objects on the current page.

Yields:

  • (ForemObject)

    each resource object on the current page.

Returns:

  • (Enumerator)

    if no block is given.



93
94
95
# File 'lib/forem/list_object.rb', line 93

def each(&block)
  @data.each(&block)
end

#empty?Boolean

Returns whether the current page contains zero items.

Returns:

  • (Boolean)

    whether the current page contains zero items.



111
112
113
# File 'lib/forem/list_object.rb', line 111

def empty?
  @data.empty?
end

#has_more?Boolean

Return whether more pages of results may exist after this one.

Inferred by checking whether the current page returned exactly #per_page items.

Returns:

  • (Boolean)


85
86
87
# File 'lib/forem/list_object.rb', line 85

def has_more?
  @data.length == @per_page && @data.length > 0
end

#lengthInteger Also known as: size

Returns the number of items on the current page.

Returns:

  • (Integer)

    the number of items on the current page.



105
106
107
# File 'lib/forem/list_object.rb', line 105

def length
  @data.length
end

#next_page(params = {}) ⇒ ListObject?

Fetch the next page of results.

Returns nil when #has_more? is false or when the fetcher signals there is no further page.

Parameters:

  • params (Hash) (defaults to: {})

    additional parameters merged on top of #filters.

Returns:



138
139
140
141
142
143
144
145
# File 'lib/forem/list_object.rb', line 138

def next_page(params = {})
  return nil unless has_more?
  if @fetcher
    @fetcher.call(:next, self, params)
  else
    fetch_page(@current_page + 1, params)
  end
end

#previous_page(params = {}) ⇒ ListObject?

Fetch the previous page of results.

Page-based: returns nil when already on page 1. Cursor-based: returns nil (cursor pagination is forward-only).

Parameters:

  • params (Hash) (defaults to: {})

    additional parameters merged on top of #filters.

Returns:



154
155
156
157
158
159
160
161
# File 'lib/forem/list_object.rb', line 154

def previous_page(params = {})
  if @fetcher
    @fetcher.call(:previous, self, params)
  else
    return nil if @current_page.nil? || @current_page <= 1
    fetch_page(@current_page - 1, params)
  end
end