Class: ActiveGraphql::Model::RelationProxy

Inherits:
Object
  • Object
show all
Includes:
Enumerable
Defined in:
lib/active_graphql/model/relation_proxy.rb

Overview

transforms all AR-like queries in to graphql requests

Constant Summary collapse

DEFAULT_BATCH_SIZE =
100

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(model, limit_number: nil, where_attributes: {}, offset_number: nil, meta_attributes: {}, order_attributes: [], output_values: []) ⇒ RelationProxy

Returns a new instance of RelationProxy.



20
21
22
23
24
25
26
27
28
# File 'lib/active_graphql/model/relation_proxy.rb', line 20

def initialize(model, limit_number: nil, where_attributes: {}, offset_number: nil, meta_attributes: {}, order_attributes: [], output_values: [])
  @model = model
  @limit_number = limit_number
  @where_attributes = where_attributes
  @offset_number = offset_number
  @meta_attributes = meta_attributes
  @order_attributes = order_attributes
  @output_values = output_values
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(method_name, *args, &block) ⇒ Object



237
238
239
240
241
242
243
# File 'lib/active_graphql/model/relation_proxy.rb', line 237

def method_missing(method_name, *args, &block)
  if model.respond_to?(method_name)
    merge(model.public_send(method_name, *args, &block))
  else
    super
  end
end

Instance Attribute Details

#output_valuesObject (readonly)

Returns the value of attribute output_values.



16
17
18
# File 'lib/active_graphql/model/relation_proxy.rb', line 16

def output_values
  @output_values
end

#where_attributesObject (readonly)

Returns the value of attribute where_attributes.



16
17
18
# File 'lib/active_graphql/model/relation_proxy.rb', line 16

def where_attributes
  @where_attributes
end

Instance Method Details

#allObject



30
31
32
# File 'lib/active_graphql/model/relation_proxy.rb', line 30

def all
  self
end

#blank?Boolean

Returns:

  • (Boolean)


221
222
223
# File 'lib/active_graphql/model/relation_proxy.rb', line 221

def blank?
  empty?
end

#countObject



91
92
93
94
95
96
# File 'lib/active_graphql/model/relation_proxy.rb', line 91

def count
  @size = begin
    total_without_offset = [total - offset_number.to_i].max
    [total_without_offset, limit_number].compact.min
  end
end

#current_pageObject



82
83
84
# File 'lib/active_graphql/model/relation_proxy.rb', line 82

def current_page
  meta_attributes.fetch(:current_page, 1)
end

#empty?Boolean

Returns:

  • (Boolean)


217
218
219
# File 'lib/active_graphql/model/relation_proxy.rb', line 217

def empty?
  count.zero?
end

#find(id) ⇒ Object

rubocop:disable Metrics/AbcSize



106
107
108
109
110
111
112
113
114
115
116
117
118
# File 'lib/active_graphql/model/relation_proxy.rb', line 106

def find(id) # rubocop:disable Metrics/AbcSize
  action = formatted_action(
    graphql_client
      .query(resource_name)
      .select(*select_attributes)
      .where(config.primary_key => id)
  )

  response = action.response
  raise Errors::RecordNotFoundError unless action.response.result

  model.new(response.result!.to_h)
end

#find_each(batch_size: DEFAULT_BATCH_SIZE) ⇒ Object



146
147
148
149
150
151
# File 'lib/active_graphql/model/relation_proxy.rb', line 146

def find_each(batch_size: DEFAULT_BATCH_SIZE)
  find_in_batches(batch_size: batch_size) do |items|
    items.each { |item| yield(item) }
  end
  self
end

#find_in_batches(*args, &block) ⇒ Object



153
154
155
# File 'lib/active_graphql/model/relation_proxy.rb', line 153

def find_in_batches(*args, &block)
  FindInBatches.call(meta(paginated: true), *args, &block)
end

#first(number_of_items = 1) ⇒ Object



128
129
130
131
132
133
134
# File 'lib/active_graphql/model/relation_proxy.rb', line 128

def first(number_of_items = 1)
  paginated_raw = formatted_action(raw.meta(paginated: true))
  result = paginated_raw.where(first: number_of_items).result!
  collection = decorate_paginated_result(result)

  number_of_items == 1 ? collection.first : collection
end

#first_batchObject



170
171
172
# File 'lib/active_graphql/model/relation_proxy.rb', line 170

def first_batch
  @first_batch ||= decorate_paginated_result(formatted_raw_response.result!)
end

#graphql_paramsObject



178
179
180
181
182
183
184
185
# File 'lib/active_graphql/model/relation_proxy.rb', line 178

def graphql_params
  {
    filter: where_attributes.presence,
    order: order_attributes.presence,
    first: limit_number,
    after: offset_number&.to_s
  }.compact
end

#last(number_of_items = 1) ⇒ Object



120
121
122
123
124
125
126
# File 'lib/active_graphql/model/relation_proxy.rb', line 120

def last(number_of_items = 1)
  paginated_raw = formatted_action(raw.meta(paginated: true))
  result = paginated_raw.where(last: number_of_items).result!
  collection = decorate_paginated_result(result)

  number_of_items == 1 ? collection.first : collection
end

#limit(limit_number) ⇒ Object



34
35
36
# File 'lib/active_graphql/model/relation_proxy.rb', line 34

def limit(limit_number)
  chain(limit_number: limit_number)
end

#merge(other_query) ⇒ Object



60
61
62
# File 'lib/active_graphql/model/relation_proxy.rb', line 60

def merge(other_query)
  where(other_query.where_attributes)
end

#meta(new_meta_attributes) ⇒ Object



68
69
70
# File 'lib/active_graphql/model/relation_proxy.rb', line 68

def meta(new_meta_attributes)
  chain(meta_attributes: meta_attributes.merge(new_meta_attributes.symbolize_keys))
end

#next_page?Boolean

Returns:

  • (Boolean)


166
167
168
# File 'lib/active_graphql/model/relation_proxy.rb', line 166

def next_page?
  raw_result.page_info.has_next_page
end

#offset(offset_number) ⇒ Object



38
39
40
# File 'lib/active_graphql/model/relation_proxy.rb', line 38

def offset(offset_number)
  chain(offset_number: offset_number)
end

#or(relation) ⇒ Object



229
230
231
# File 'lib/active_graphql/model/relation_proxy.rb', line 229

def or(relation)
  BuildOrRelation.call(self, relation)
end

#order(*order_params) ⇒ Object



191
192
193
# File 'lib/active_graphql/model/relation_proxy.rb', line 191

def order(*order_params)
  chain(order_attributes: order_params_attributes(order_params))
end

#order_param_attributes(order_by, direction) ⇒ Object



209
210
211
212
213
214
215
# File 'lib/active_graphql/model/relation_proxy.rb', line 209

def order_param_attributes(order_by, direction)
  {
    by: order_by&.to_s&.upcase,
    direction: direction&.to_s&.upcase,
    __keyword_attributes: %i[by direction]
  }
end

#order_params_attributes(order_params) ⇒ Object



195
196
197
198
199
# File 'lib/active_graphql/model/relation_proxy.rb', line 195

def order_params_attributes(order_params)
  send(:order_attributes) + order_params.compact
    .flat_map { |order_param| ordering_attributes(order_param) }
    .select(&:compact)
end

#ordering_attributes(order_param) ⇒ Object



201
202
203
204
205
206
207
# File 'lib/active_graphql/model/relation_proxy.rb', line 201

def ordering_attributes(order_param)
  if order_param.is_a?(Hash)
    order_param.map { |param, direction| order_param_attributes(param, direction) }
  else
    order_param_attributes(order_param, :asc)
  end
end

#page(page_number = 1) ⇒ Object



72
73
74
# File 'lib/active_graphql/model/relation_proxy.rb', line 72

def page(page_number = 1)
  paginate(page: page_number)
end

#paginate(page: nil, per_page: 100) ⇒ Object



76
77
78
79
80
# File 'lib/active_graphql/model/relation_proxy.rb', line 76

def paginate(page: nil, per_page: 100)
  page_number = [page.to_i, 1].max
  offset = (page_number - 1) * per_page
  limit(per_page).offset(offset).meta(current_page: page_number, per_page: per_page)
end

#pluck(*attributes) ⇒ Object



136
137
138
139
140
141
142
143
144
# File 'lib/active_graphql/model/relation_proxy.rb', line 136

def pluck(*attributes)
  map do |record|
    if attributes.count > 1
      attributes.map { |attribute| record.public_send(attribute) }
    else
      record.public_send(attributes.first)
    end
  end
end

#present?Boolean

Returns:

  • (Boolean)


225
226
227
# File 'lib/active_graphql/model/relation_proxy.rb', line 225

def present?
  !blank?
end

#raw_resultObject



174
175
176
# File 'lib/active_graphql/model/relation_proxy.rb', line 174

def raw_result
  formatted_raw_response.result
end

#reselect(*array_outputs, **hash_outputs) ⇒ Object



51
52
53
54
# File 'lib/active_graphql/model/relation_proxy.rb', line 51

def reselect(*array_outputs, **hash_outputs)
  outputs = join_array_and_hash(*array_outputs, **hash_outputs)
  chain(output_values: outputs)
end

#respond_to_missing?(method_name, *args, &block) ⇒ Boolean

Returns:

  • (Boolean)


233
234
235
# File 'lib/active_graphql/model/relation_proxy.rb', line 233

def respond_to_missing?(method_name, *args, &block)
  model.respond_to?(method_name) || super
end

#select(*array_outputs, **hash_outputs) ⇒ Object



46
47
48
49
# File 'lib/active_graphql/model/relation_proxy.rb', line 46

def select(*array_outputs, **hash_outputs)
  full_array_outputs = (output_values + array_outputs).uniq
  reselect(*full_array_outputs, **hash_outputs)
end

#select_attributesObject



56
57
58
# File 'lib/active_graphql/model/relation_proxy.rb', line 56

def select_attributes
  output_values.presence || config.attributes_graphql_output
end

#sizeObject



102
103
104
# File 'lib/active_graphql/model/relation_proxy.rb', line 102

def size
  @size ||= count
end

#to_aObject



157
158
159
160
161
162
163
164
# File 'lib/active_graphql/model/relation_proxy.rb', line 157

def to_a
  return @to_a if defined?(@to_a)

  list = []
  find_in_batches { |batch| list += batch }

  @to_a = list
end

#to_graphqlObject



187
188
189
# File 'lib/active_graphql/model/relation_proxy.rb', line 187

def to_graphql
  formatted_action(raw.meta(paginated: true)).to_graphql
end

#totalObject



98
99
100
# File 'lib/active_graphql/model/relation_proxy.rb', line 98

def total
  formatted_raw.reselect(:total).result.total
end

#total_pagesObject



86
87
88
89
# File 'lib/active_graphql/model/relation_proxy.rb', line 86

def total_pages
  last_page = (total.to_f / meta_attributes.fetch(:per_page, 100)).ceil
  [last_page, 1].max
end

#unscope(where:) ⇒ Object



64
65
66
# File 'lib/active_graphql/model/relation_proxy.rb', line 64

def unscope(where:)
  chain(where_attributes: where_attributes.except(where))
end

#where(new_where_attributes) ⇒ Object



42
43
44
# File 'lib/active_graphql/model/relation_proxy.rb', line 42

def where(new_where_attributes)
  chain(where_attributes: where_attributes.deep_merge(new_where_attributes.symbolize_keys))
end