Class: Frame::ListObject

Inherits:
FrameObject show all
Includes:
Enumerable, APIOperations::Request
Defined in:
lib/frame/list_object.rb

Instance Attribute Summary collapse

Attributes inherited from FrameObject

#id, #original_values

Class Method Summary collapse

Instance Method Summary collapse

Methods included from APIOperations::Request

included

Methods inherited from FrameObject

#[]=, #initialize_from, #keys, #serialize_params, #to_s, #update_attributes, #values

Constructor Details

#initialize(data = {}, opts = {}) ⇒ ListObject

Returns a new instance of ListObject.



11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# File 'lib/frame/list_object.rb', line 11

def initialize(data = {}, opts = {})
  super(nil, opts)
  @data = data[:data] || []
  @filters = {}
  @resource_url = opts[:resource_url]
  @has_more = data[:meta] && data[:meta][:has_more]
  @page = data[:meta] && data[:meta][:page] || 1

  # Extract per_page from URL if available
  @per_page = if data.dig(:meta, :url)&.include?("per_page=")
    begin
      data[:meta][:url].match(/per_page=(\d+)/)[1].to_i
    rescue
      10
    end
  else
    10
  end
end

Instance Attribute Details

#dataObject (readonly)

Returns the value of attribute data.



9
10
11
# File 'lib/frame/list_object.rb', line 9

def data
  @data
end

#filtersObject

Returns the value of attribute filters.



8
9
10
# File 'lib/frame/list_object.rb', line 8

def filters
  @filters
end

#resource_urlObject (readonly)

Returns the value of attribute resource_url.



9
10
11
# File 'lib/frame/list_object.rb', line 9

def resource_url
  @resource_url
end

Class Method Details

.construct_from(values, opts = {}) ⇒ Object



31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
# File 'lib/frame/list_object.rb', line 31

def self.construct_from(values, opts = {})
  data = values || {}

  # Initialize from the values - excluding the :data key to avoid accessor conflicts
  # We'll handle data manually since it's declared as an attribute
  obj = new(data, opts)

  # Store original values except data
  values_without_data = values.dup
  data_array = values_without_data.delete(:data)

  # Initialize from values without data first
  obj.initialize_from(values_without_data, opts)

  # Then process the data array
  if data_array&.is_a?(Array)
    converted_data = data_array.map { |item| Util.convert_to_frame_object(item, opts) }
    obj.instance_variable_set(:@data, converted_data)
  end

  obj
end

.empty_list(opts = {}) ⇒ Object



54
55
56
# File 'lib/frame/list_object.rb', line 54

def self.empty_list(opts = {})
  construct_from({data: [], meta: {has_more: false, page: 1}}, opts)
end

Instance Method Details

#[](index) ⇒ Object



58
59
60
# File 'lib/frame/list_object.rb', line 58

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

#each(&blk) ⇒ Object



62
63
64
# File 'lib/frame/list_object.rb', line 62

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

#empty?Boolean

Returns:

  • (Boolean)


66
67
68
# File 'lib/frame/list_object.rb', line 66

def empty?
  @data.empty?
end

#firstObject



70
71
72
# File 'lib/frame/list_object.rb', line 70

def first
  @data.first
end

#has_more?Boolean

Returns:

  • (Boolean)


112
113
114
# File 'lib/frame/list_object.rb', line 112

def has_more?
  !!@has_more
end

#inspectObject



131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
# File 'lib/frame/list_object.rb', line 131

def inspect
  meta_info = "#<#{self.class.name}:0x#{object_id.to_s(16)} @page=#{@page} @per_page=#{@per_page} @has_more=#{@has_more} items=#{@data.size}>"

  # If data is empty, just return meta info
  return meta_info if @data.empty?

  # Format each item in the data array
  data_strings = @data.map do |item|
    if item.is_a?(FrameObject) && item.respond_to?(:id) && item.id
      obj_name = item.class.name.split("::").last
      "  #<#{obj_name}:#{item.id} #{item.inspect}>"
    else
      "  #{item.inspect}"
    end
  end

  "#{meta_info}\ndata=[\n#{data_strings.join(",\n")}\n]"
end

#lastObject



74
75
76
# File 'lib/frame/list_object.rb', line 74

def last
  @data.last
end

#next_page(params = {}, opts = {}) ⇒ Object



84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
# File 'lib/frame/list_object.rb', line 84

def next_page(params = {}, opts = {})
  return self.class.empty_list(opts) unless has_more?

  params = filters.merge(params || {})
  next_page_num = @page + 1 if @page
  params[:page] = next_page_num
  params[:per_page] = @per_page if @per_page

  # Get the resource URL - try all possible fallbacks
  url = resource_url ||
    (self.class.respond_to?(:resource_url) ? self.class.resource_url : nil) ||
    "/v1/customers" # Default if we can't determine it

  response = request(:get, url, params, opts)
  result = Util.convert_to_frame_object(response, opts)

  # Update this object's state with the next page's data
  if result && !result.empty?
    @page = next_page_num
    @data = result.data
    @has_more = result.has_more?

    self
  else
    result
  end
end

#retrieve(id, opts = {}) ⇒ Object



78
79
80
81
82
# File 'lib/frame/list_object.rb', line 78

def retrieve(id, opts = {})
  resource_class = object_class_for_data
  return resource_class.retrieve(id, opts) if resource_class
  nil
end

#to_hashObject



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

def to_hash
  {
    data: @data.map { |i| i.is_a?(FrameObject) ? i.to_hash : i },
    meta: {
      has_more: has_more?,
      page: @page,
      per_page: @per_page
    }
  }
end

#total_countObject



116
117
118
# File 'lib/frame/list_object.rb', line 116

def total_count
  @data.size
end