Class: CardDB::Collection

Inherits:
Object
  • Object
show all
Includes:
Enumerable
Defined in:
lib/carddb/collection.rb

Overview

Represents a paginated collection of results from the API. Implements Enumerable for easy iteration.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(data, item_class: nil, next_page_loader: nil, client: nil) ⇒ Collection

Returns a new instance of Collection.

Parameters:

  • data (Hash)

    The connection data from GraphQL response

  • item_class (Class, nil) (defaults to: nil)

    Optional class to wrap items

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

    Proc to load next page

  • client (Client, nil) (defaults to: nil)

    Client instance for making related queries



25
26
27
28
29
30
# File 'lib/carddb/collection.rb', line 25

def initialize(data, item_class: nil, next_page_loader: nil, client: nil)
  @total_count = data['totalCount']
  @page_info = PageInfo.new(data['pageInfo']) if data['pageInfo']
  @items = parse_items(data['edges'] || [], item_class, client)
  @next_page_loader = next_page_loader
end

Instance Attribute Details

#itemsArray (readonly)

Returns The items in this page.

Returns:

  • (Array)

    The items in this page



16
17
18
# File 'lib/carddb/collection.rb', line 16

def items
  @items
end

#next_page_loaderProc? (readonly)

Returns Proc to fetch the next page.

Returns:

  • (Proc, nil)

    Proc to fetch the next page



19
20
21
# File 'lib/carddb/collection.rb', line 19

def next_page_loader
  @next_page_loader
end

#page_infoHash (readonly)

Returns Page info with cursor data.

Returns:

  • (Hash)

    Page info with cursor data



13
14
15
# File 'lib/carddb/collection.rb', line 13

def page_info
  @page_info
end

#total_countInteger (readonly)

Returns Total count of matching records.

Returns:

  • (Integer)

    Total count of matching records



10
11
12
# File 'lib/carddb/collection.rb', line 10

def total_count
  @total_count
end

Instance Method Details

#auto_paginateEnumerator::Lazy

Returns a lazy enumerator that auto-paginates through all results.

Returns:

  • (Enumerator::Lazy)


79
80
81
82
83
84
85
86
87
88
89
90
# File 'lib/carddb/collection.rb', line 79

def auto_paginate
  Enumerator.new do |yielder|
    current = self
    loop do
      current.each { |item| yielder << item }
      break unless current.next_page?

      current = current.next_page
      break if current.nil?
    end
  end.lazy
end

#each(&block) ⇒ Object

Iterate over items



33
34
35
# File 'lib/carddb/collection.rb', line 33

def each(&block)
  items.each(&block)
end

#empty?Boolean

Check if collection is empty

Returns:

  • (Boolean)


164
165
166
# File 'lib/carddb/collection.rb', line 164

def empty?
  items.empty?
end

#end_cursorString?

Get the cursor for the next page

Returns:

  • (String, nil)


54
55
56
# File 'lib/carddb/collection.rb', line 54

def end_cursor
  page_info&.end_cursor
end

#find_each(batch_size: 100) {|item| ... } ⇒ void

This method returns an undefined value.

Iterates through all results, automatically paginating as needed. Similar to ActiveRecord’s find_each.

Examples:

collection.find_each do |record|
  puts record.name
end

With custom batch size

collection.find_each(batch_size: 50) do |record|
  process(record)
end

Parameters:

  • batch_size (Integer) (defaults to: 100)

    Number of records per API request (default: 100, max: 100)

Yields:

  • (item)

    Each item in the collection



108
109
110
111
112
113
114
# File 'lib/carddb/collection.rb', line 108

def find_each(batch_size: 100, &block)
  return enum_for(:find_each, batch_size: batch_size) unless block_given?

  find_in_batches(batch_size: batch_size) do |batch|
    batch.each(&block)
  end
end

#find_in_batches(batch_size: 100) {|batch| ... } ⇒ void

This method returns an undefined value.

Yields batches of records, automatically paginating as needed. Similar to ActiveRecord’s find_in_batches.

Examples:

collection.find_in_batches(batch_size: 50) do |batch|
  batch.each { |record| process(record) }
end

Parameters:

  • batch_size (Integer) (defaults to: 100)

    Number of records per batch/API request (default: 100, max: 100)

Yields:

  • (batch)

    Array of items for each batch



127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
# File 'lib/carddb/collection.rb', line 127

def find_in_batches(batch_size: 100)
  return enum_for(:find_in_batches, batch_size: batch_size) unless block_given?

  # Clamp batch_size to valid range
  [[batch_size, 1].max, 100].min

  # For the first batch, we use the items already loaded
  # (they may have been fetched with a different page size, but that's ok)
  current = self

  loop do
    # Yield the current page's items
    yield current.items unless current.items.empty?

    # Stop if no more pages
    break unless current.next_page?

    # Fetch next page with the specified batch_size
    # Note: The next_page_loader uses the original 'first' parameter,
    # but subsequent pages will use the original size.
    # To truly control batch_size, we'd need to modify the loader.
    current = current.next_page
    break if current.nil?
  end
end

#firstObject?

Get first item

Returns:

  • (Object, nil)


171
172
173
# File 'lib/carddb/collection.rb', line 171

def first
  items.first
end

#lastObject?

Get last item

Returns:

  • (Object, nil)


178
179
180
# File 'lib/carddb/collection.rb', line 178

def last
  items.last
end

#next_pageCollection?

Fetch the next page of results

Returns:

  • (Collection, nil)

    The next page, or nil if no more pages

Raises:



69
70
71
72
73
74
# File 'lib/carddb/collection.rb', line 69

def next_page
  return nil unless next_page?
  raise Error, 'No next page loader configured' unless next_page_loader

  next_page_loader.call(end_cursor)
end

#next_page?Boolean

Check if there are more pages

Returns:

  • (Boolean)


40
41
42
# File 'lib/carddb/collection.rb', line 40

def next_page?
  page_info&.has_next_page || false
end

#previous_page?Boolean

Check if there are previous pages

Returns:

  • (Boolean)


47
48
49
# File 'lib/carddb/collection.rb', line 47

def previous_page?
  page_info&.has_previous_page || false
end

#sizeInteger Also known as: length

Get number of items in current page

Returns:

  • (Integer)


156
157
158
# File 'lib/carddb/collection.rb', line 156

def size
  items.size
end

#start_cursorString?

Get the cursor for the previous page

Returns:

  • (String, nil)


61
62
63
# File 'lib/carddb/collection.rb', line 61

def start_cursor
  page_info&.start_cursor
end