Class: MOCO::CollectionProxy

Inherits:
Object
  • Object
show all
Includes:
Enumerable
Defined in:
lib/moco/collection_proxy.rb

Overview

Provides ActiveRecord-style query interface for MOCO entities

Direct Known Subclasses

NestedCollectionProxy

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(client, path_or_entity_name, entity_class_name) ⇒ CollectionProxy

Returns a new instance of CollectionProxy.



9
10
11
12
13
14
15
16
17
18
# File 'lib/moco/collection_proxy.rb', line 9

def initialize(client, path_or_entity_name, entity_class_name)
  @client = client
  @entity_class_name = entity_class_name
  @entity_class = load_entity_class # Load and store the class
  @base_path = determine_base_path(path_or_entity_name)
  @filters = {} # Store query filters
  @limit_value = nil # Store limit for methods like first/find_by
  @loaded = false # Flag to track if data has been fetched
  @records = [] # Cache for fetched records
end

Instance Attribute Details

#clientObject (readonly)

Returns the value of attribute client.



7
8
9
# File 'lib/moco/collection_proxy.rb', line 7

def client
  @client
end

#entity_class_nameObject (readonly)

Returns the value of attribute entity_class_name.



7
8
9
# File 'lib/moco/collection_proxy.rb', line 7

def entity_class_name
  @entity_class_name
end

#filtersObject (readonly)

Returns the value of attribute filters.



7
8
9
# File 'lib/moco/collection_proxy.rb', line 7

def filters
  @filters
end

#limit_valueObject (readonly)

Returns the value of attribute limit_value.



7
8
9
# File 'lib/moco/collection_proxy.rb', line 7

def limit_value
  @limit_value
end

Instance Method Details

#allObject

Fetches all records matching the current filters. Caches the result.



68
69
70
71
# File 'lib/moco/collection_proxy.rb', line 68

def all
  load_records unless loaded?
  @records
end

#assignedObject

Modifies the base path to fetch assigned resources. Returns self.



58
59
60
61
62
# File 'lib/moco/collection_proxy.rb', line 58

def assigned
  # Ensure this is only called once or handle idempotency if needed
  @base_path += "/assigned"
  self
end

#create(attributes) ⇒ Object

— Persistence Methods (Pass-through) — These don’t typically belong on the relation/proxy but are kept for now. Consider moving them or ensuring they operate correctly in this context.



111
112
113
114
115
116
# File 'lib/moco/collection_proxy.rb', line 111

def create(attributes)
  klass = entity_class
  return nil unless klass && klass <= MOCO::BaseEntity

  klass.new(client, client.post(@base_path, attributes))
end

#delete(id) ⇒ Object



125
126
127
# File 'lib/moco/collection_proxy.rb', line 125

def delete(id)
  client.delete("#{@base_path}/#{id}")
end

#eachObject

Executes the query and yields each record.



102
103
104
105
# File 'lib/moco/collection_proxy.rb', line 102

def each(&)
  load_records unless loaded?
  @records.each(&)
end

#find(id) ⇒ Object

Fetches a specific record by ID. Does not use current filters or limit.



74
75
76
77
78
79
80
81
82
83
84
85
# File 'lib/moco/collection_proxy.rb', line 74

def find(id)
  # Ensure entity_class is loaded and valid before calling new
  klass = entity_class
  return nil unless klass && klass <= MOCO::BaseEntity

  # Directly fetch by ID, bypassing stored filters/limit
  response = client.get("#{@base_path}/#{id}")
  # wrap_response now returns an array even for single results
  result_array = wrap_response(response)
  # Return the single entity or nil if not found (or if response was not a hash)
  result_array.first
end

#find_by(conditions) ⇒ Object

Finds the first record matching the given attributes.



97
98
99
# File 'lib/moco/collection_proxy.rb', line 97

def find_by(conditions)
  where(conditions).first
end

#firstObject

Fetches the first record matching the current filters.



91
92
93
94
# File 'lib/moco/collection_proxy.rb', line 91

def first
  limit(1).load_records unless loaded? && @limit_value == 1
  @records.first
end

#limit(value) ⇒ Object

Sets a limit on the number of records to fetch. Returns self.



52
53
54
55
# File 'lib/moco/collection_proxy.rb', line 52

def limit(value)
  @limit_value = value
  self
end

#load_entity_classObject



20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# File 'lib/moco/collection_proxy.rb', line 20

def load_entity_class
  # Ensure ActiveSupport::Inflector is available if not already loaded globally
  require "active_support/inflector" unless defined?(ActiveSupport::Inflector)

  entity_file_name = ActiveSupport::Inflector.underscore(entity_class_name)
  entity_file_path = "entities/#{entity_file_name}" # Path relative to lib/moco/
  begin
    # Use require_relative from the current file's directory
    require_relative entity_file_path
    MOCO.const_get(entity_class_name)
  rescue LoadError
    warn "Warning: Could not load entity file at #{entity_file_path}. Using BaseEntity."
    MOCO::BaseEntity # Fallback
  rescue NameError
    warn "Warning: Could not find entity class #{entity_class_name}. Using BaseEntity."
    MOCO::BaseEntity # Fallback
  end
end

#load_recordsObject

Executes the API request based on current filters and limit. Populates @records and sets @loaded flag. Needs to be public for methods like first, each, find_by to call it.



134
135
136
137
138
139
140
141
142
143
144
145
146
147
# File 'lib/moco/collection_proxy.rb', line 134

def load_records
  query_params = @filters.dup
  query_params[:limit] = @limit_value if @limit_value
  # MOCO API might use 'per_page' instead of 'limit' for pagination control
  # Adjust if necessary based on API docs. Assuming 'limit' works for now.

  # Filter out nil values before sending to avoid empty params like ?from&to=
  query_params.compact!

  response = client.get(@base_path, query_params)
  @records = wrap_response(response) # wrap_response should return an Array here
  @loaded = true
  @records # Return the loaded records
end

#update(id, attributes) ⇒ Object



118
119
120
121
122
123
# File 'lib/moco/collection_proxy.rb', line 118

def update(id, attributes)
  klass = entity_class
  return nil unless klass && klass <= MOCO::BaseEntity

  klass.new(client, client.put("#{@base_path}/#{id}", attributes))
end

#where(conditions = {}) ⇒ Object

Adds filters to the query. Returns self for chaining.



45
46
47
48
49
# File 'lib/moco/collection_proxy.rb', line 45

def where(conditions = {})
  # TODO: Implement proper merging/handling of existing filters if called multiple times
  @filters.merge!(conditions)
  self # Return self to allow chaining like client.projects.where(active: true).where(...)
end