class ActiveGraphql::Model::RelationProxy

transforms all AR-like queries in to graphql requests

Constants

DEFAULT_BATCH_SIZE

Attributes

limit_number[R]
meta_attributes[R]
model[R]
offset_number[R]
order_attributes[R]
output_values[R]
where_attributes[R]

Public Class Methods

new(model, limit_number: nil, where_attributes: {}, offset_number: nil, meta_attributes: {}, order_attributes: [], output_values: []) click to toggle source
# 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

Public Instance Methods

all() click to toggle source
# File lib/active_graphql/model/relation_proxy.rb, line 30
def all
  self
end
blank?() click to toggle source
# File lib/active_graphql/model/relation_proxy.rb, line 221
def blank?
  empty?
end
count() click to toggle source
# 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_page() click to toggle source
# File lib/active_graphql/model/relation_proxy.rb, line 82
def current_page
  meta_attributes.fetch(:current_page, 1)
end
empty?() click to toggle source
# File lib/active_graphql/model/relation_proxy.rb, line 217
def empty?
  count.zero?
end
find(id) click to toggle source
# 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) { |item| ... } click to toggle source
# 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) click to toggle source
# 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) click to toggle source
# 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_batch() click to toggle source
# File lib/active_graphql/model/relation_proxy.rb, line 170
def first_batch
  @first_batch ||= decorate_paginated_result(formatted_raw_response.result!)
end
graphql_params() click to toggle source
# 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) click to toggle source
# 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) click to toggle source
# File lib/active_graphql/model/relation_proxy.rb, line 34
def limit(limit_number)
  chain(limit_number: limit_number)
end
merge(other_query) click to toggle source
# File lib/active_graphql/model/relation_proxy.rb, line 60
def merge(other_query)
  where(other_query.where_attributes)
end
meta(new_meta_attributes) click to toggle source
# 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
method_missing(method_name, *args, &block) click to toggle source
Calls superclass method
# 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
next_page?() click to toggle source
# File lib/active_graphql/model/relation_proxy.rb, line 166
def next_page?
  raw_result.page_info.has_next_page
end
offset(offset_number) click to toggle source
# File lib/active_graphql/model/relation_proxy.rb, line 38
def offset(offset_number)
  chain(offset_number: offset_number)
end
or(relation) click to toggle source
# File lib/active_graphql/model/relation_proxy.rb, line 229
def or(relation)
  BuildOrRelation.call(self, relation)
end
order(*order_params) click to toggle source
# 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) click to toggle source
# 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) click to toggle source
# 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) click to toggle source
# 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) click to toggle source
# 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) click to toggle source
# 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) click to toggle source
# 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?() click to toggle source
# File lib/active_graphql/model/relation_proxy.rb, line 225
def present?
  !blank?
end
raw_result() click to toggle source
# File lib/active_graphql/model/relation_proxy.rb, line 174
def raw_result
  formatted_raw_response.result
end
reselect(*array_outputs, **hash_outputs) click to toggle source
# 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) click to toggle source
Calls superclass method
# 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) click to toggle source
# 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_attributes() click to toggle source
# File lib/active_graphql/model/relation_proxy.rb, line 56
def select_attributes
  output_values.presence || config.attributes_graphql_output
end
size() click to toggle source
# File lib/active_graphql/model/relation_proxy.rb, line 102
def size
  @size ||= count
end
to_a() click to toggle source
# 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_graphql() click to toggle source
# File lib/active_graphql/model/relation_proxy.rb, line 187
def to_graphql
  formatted_action(raw.meta(paginated: true)).to_graphql
end
total() click to toggle source
# File lib/active_graphql/model/relation_proxy.rb, line 98
def total
  formatted_raw.reselect(:total).result.total
end
total_pages() click to toggle source
# 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:) click to toggle source
# 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) click to toggle source
# 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

Private Instance Methods

chain( limit_number: send(:limit_number), where_attributes: send(:where_attributes), meta_attributes: send(:meta_attributes), offset_number: send(:offset_number), order_attributes: send(:order_attributes), output_values: send(:output_values) ) click to toggle source
# File lib/active_graphql/model/relation_proxy.rb, line 289
def chain(
  limit_number: send(:limit_number),
  where_attributes: send(:where_attributes),
  meta_attributes: send(:meta_attributes),
  offset_number: send(:offset_number),
  order_attributes: send(:order_attributes),
  output_values: send(:output_values)
)
  self.class.new(
    model,
    limit_number: limit_number,
    where_attributes: where_attributes,
    meta_attributes: meta_attributes,
    offset_number: offset_number,
    order_attributes: order_attributes,
    output_values: output_values
  )
end
config() click to toggle source
# File lib/active_graphql/model/relation_proxy.rb, line 312
def config
  model.active_graphql
end
decorate_paginated_result(result) click to toggle source
# File lib/active_graphql/model/relation_proxy.rb, line 271
def decorate_paginated_result(result)
  result.edges.map { |it| model.new(it.node.to_h) }
end
formatted_action(action) click to toggle source
# File lib/active_graphql/model/relation_proxy.rb, line 263
def formatted_action(action)
  config.formatter.call(action)
end
formatted_raw() click to toggle source
# File lib/active_graphql/model/relation_proxy.rb, line 267
def formatted_raw
  formatted_action(raw)
end
formatted_raw_response() click to toggle source
# File lib/active_graphql/model/relation_proxy.rb, line 249
def formatted_raw_response
  @formatted_raw_response ||= formatted_raw.response
end
graphql_client() click to toggle source
# File lib/active_graphql/model/relation_proxy.rb, line 308
def graphql_client
  config.graphql_client
end
join_array_and_hash(*array, **hash) click to toggle source
# File lib/active_graphql/model/relation_proxy.rb, line 316
def join_array_and_hash(*array, **hash)
  array + hash.map { |k, v| { k => v } }
end
raw() click to toggle source
# File lib/active_graphql/model/relation_proxy.rb, line 253
def raw
  @raw ||= begin
    graphql_client
      .query(resource_plural_name)
      .meta(meta_attributes)
      .select(select_attributes)
      .where(graphql_params)
  end
end
resource_name() click to toggle source
# File lib/active_graphql/model/relation_proxy.rb, line 282
def resource_name
  @resource_name ||= begin
    name = config.resource_name&.to_s || model.name.demodulize
    name
  end
end
resource_plural_name() click to toggle source
# File lib/active_graphql/model/relation_proxy.rb, line 275
def resource_plural_name
  @resource_plural_name ||= begin
    name = config.resource_plural_name&.to_s || resource_name.pluralize
    name
  end
end