class ActiveShotgun::AssociationsProxy

Public Class Methods

new(base_class:, base_id:, field_name:, possible_types: {}) click to toggle source
# File lib/active_shotgun/associations_proxy.rb, line 5
def initialize(base_class:, base_id:, field_name:, possible_types: {})
  @base_class = base_class
  @base_id = base_id
  @field_name = field_name
  @possible_types = possible_types
  @queries =
    possible_types.map do |type, klass|
      Query.new(type: type, klass: klass)
    end
  @global_limit = 1000
  @global_offset = 0
  @global_orders = nil
  @global_fields = nil
end

Public Instance Methods

<<(model)
Alias for: push
all() click to toggle source
# File lib/active_shotgun/associations_proxy.rb, line 65
def all
  @array ||= resolve_all_queries # rubocop:disable Naming/MemoizedInstanceVariableName
end
Also aliased as: to_a
delete(id, type = nil) click to toggle source
# File lib/active_shotgun/associations_proxy.rb, line 41
def delete(id, type = nil)
  raise "Many types possible. Please specify." if !type && has_many_types?

  type ||= @possible_types.keys.first
  already_here =
    @queries.reduce([]) do |result, query|
      result + query.dup.limit(1000).pluck(:id).map{ |item_id|
                 { type: query.instance_variable_get(:@type), id: item_id }
               }
    end
  new_items = already_here.reject{ |item| item[:type] == type && item[:id] == id }

  Client.shotgun.entities(@base_class.to_s).update(
    @base_id,
    @field_name => new_items.uniq
  )
  @array = nil
  true
end
find_by(conditions) click to toggle source
# File lib/active_shotgun/associations_proxy.rb, line 107
def find_by(conditions)
  where(conditions).first
end
first(number = 1) click to toggle source
# File lib/active_shotgun/associations_proxy.rb, line 70
def first(number = 1)
  results = limit(number).all
  if @global_limit == 1
    results.first
  else
    results
  end
end
has_many_types?() click to toggle source
# File lib/active_shotgun/associations_proxy.rb, line 61
def has_many_types?
  @has_many_types ||= @queries.size > 1
end
limit(number) click to toggle source
# File lib/active_shotgun/associations_proxy.rb, line 79
def limit(number)
  @global_limit = number
  @queries =
    @queries.map do |query|
      has_many_types? ? query.limit(1000) : query.limit(number)
    end
  self
end
offset(number) click to toggle source
# File lib/active_shotgun/associations_proxy.rb, line 88
def offset(number)
  @global_offset = number
  @queries =
    @queries.map do |query|
      has_many_types? ? query : query.offset(number)
    end
  @array = nil
  self
end
orders(new_orders) click to toggle source
# File lib/active_shotgun/associations_proxy.rb, line 111
def orders(new_orders)
  @global_orders = new_orders
  @queries =
    @queries.map do |query|
      query.orders(new_orders)
    end
  @array = nil
  self
end
pluck(*fields) click to toggle source
# File lib/active_shotgun/associations_proxy.rb, line 130
def pluck(*fields)
  fields.flatten!
  result = select(fields).map{ |e| fields.map{ |field| e.public_send(field) } }
  fields.size == 1 ? result.flatten : result
end
push(model) click to toggle source
# File lib/active_shotgun/associations_proxy.rb, line 20
def push(model)
  already_here =
    @queries.reduce([]) do |result, query|
      result + query.dup.limit(1000).pluck(:id).map{ |id|
                 { type: query.instance_variable_get(:@type), id: id }
               }
    end
  Client.shotgun.entities(@base_class.to_s).update(
    @base_id,
    @field_name => already_here.push(
      {
        type: model.class.shotgun_type,
        id: model.id,
      }
    ).uniq
  )
  @array = nil
  true
end
Also aliased as: <<
select(*fields) click to toggle source
# File lib/active_shotgun/associations_proxy.rb, line 121
def select(*fields)
  @queries =
    @queries.map do |query|
      query.select(fields)
    end
  @array = nil
  self
end
to_a()
Alias for: all
where(conditions) click to toggle source
# File lib/active_shotgun/associations_proxy.rb, line 98
def where(conditions)
  @queries =
    @queries.map do |query|
      query.where(conditions)
    end
  @array = nil
  self
end

Private Instance Methods

global_orders_to_h() click to toggle source
# File lib/active_shotgun/associations_proxy.rb, line 147
def global_orders_to_h
  case @global_orders
  when Hash # rubocop:disable Lint/EmptyWhen
  when Array
    @global_orders.map do |str|
      [str.gsub(/^[-+]/, '').to_sym, str.start_with?('-') ? :desc : :asc]
    end
  when String
    @global_orders = @global_orders.split(/\s*,\s*/)
    global_orders_to_h
  else
    raise "Unknown order type"
  end
end
resolve_all_queries() click to toggle source
# File lib/active_shotgun/associations_proxy.rb, line 180
def resolve_all_queries
  if has_many_types?
    results = @queries.flat_map(&:to_a)
    results = sort_results(results)
    results.shift(@global_offset).first(@global_limit)
  else
    @queries.flat_map(&:to_a)
  end
end
sort_results(results) click to toggle source
# File lib/active_shotgun/associations_proxy.rb, line 162
def sort_results(results)
  orders = global_orders_to_h
  results.sort do |a, b|
    orders.reduce(0) do |res, order|
      if res == 0
        field = order.first
        if order.last == :asc
          a.public_send(field) <=> b.public_send(field)
        else
          b.public_send(field) <=> a.public_send(field)
        end
      else
        res
      end
    end
  end
end