class ReactiveRecord::ServerDataCache::CacheItem

Attributes

absolute_vector[R]
acting_user[R]
record_chain[R]
root[R]
vector[R]

Public Class Methods

new(db_cache, acting_user, klass, preloaded_records) click to toggle source
Calls superclass method
# File lib/reactive_record/server_data_cache.rb, line 152
def self.new(db_cache, acting_user, klass, preloaded_records)
  klass_constant = klass.constantize
  if existing = db_cache.detect { |cached_item| cached_item.vector == [klass_constant] }
    return existing
  end
  super
end
new(db_cache, acting_user, klass, preloaded_records) click to toggle source
# File lib/reactive_record/server_data_cache.rb, line 160
def initialize(db_cache, acting_user, klass, preloaded_records)
  klass = klass.constantize
  @db_cache = db_cache
  @acting_user = acting_user
  @vector = @absolute_vector = [klass]
  @ar_object = klass
  @record_chain = []
  @parent = nil
  @root = self
  @preloaded_records = preloaded_records
  db_cache << self
end

Public Instance Methods

aggregation?(method) click to toggle source
# File lib/reactive_record/server_data_cache.rb, line 207
def aggregation?(method)
  if method.is_a?(String) && value.class.respond_to?(:reflect_on_aggregation)
    aggregation = value.class.reflect_on_aggregation(method.to_sym)
    if aggregation && !(aggregation.klass < ActiveRecord::Base) && value.send(method)
      aggregation
    end
  end
end
apply_method(method) click to toggle source
# File lib/reactive_record/server_data_cache.rb, line 245
def apply_method(method)
  if method.is_a? Array and method.first == "find_by_id"
    method[0] = "find"
  elsif method.is_a? String and method =~ /^\*[0-9]+$/
    method = "*"
  end
  new_vector = vector + [method]
  @db_cache.detect { |cached_item| cached_item.vector == new_vector} || apply_method_to_cache(method)
end
apply_method_to_cache(method) click to toggle source
# File lib/reactive_record/server_data_cache.rb, line 173
def apply_method_to_cache(method)
  @db_cache.inject(nil) do | representative, cache_item |
    if cache_item.vector == vector
      if @ar_object.class < ActiveRecord::Base and @ar_object.attributes.has_key?(method)
        @ar_object.check_permission_with_acting_user(acting_user, :view_permitted?, method)
      end
      if method == "*"
        cache_item.apply_star || representative
      elsif method == "*all"
        cache_item.build_new_cache_item(cache_item.value.collect { |record| record.id }, method, method)
      elsif method == "*count"
        cache_item.build_new_cache_item(cache_item.value.count, method, method)
      elsif preloaded_value = @preloaded_records[cache_item.absolute_vector + [method]]
        cache_item.build_new_cache_item(preloaded_value, method, method)
      elsif aggregation = cache_item.aggregation?(method)
        cache_item.build_new_cache_item(aggregation.mapping.collect { |attribute, accessor| cache_item.value[attribute] }, method, method)
      else
        begin
          cache_item.build_new_cache_item(cache_item.value.send(*method), method, method)
        rescue Exception => e
          if cache_item.value and cache_item.value != []
            ReactiveRecord::Pry::rescued(e)
            raise e, "ReactiveRecord exception caught when applying #{method} to db object #{cache_item.value}: #{e}", e.backtrace
          else
            representative
          end
        end
      end
    else
      representative
    end
  end
end
apply_star() click to toggle source
# File lib/reactive_record/server_data_cache.rb, line 216
def apply_star
  if value && value.length > 0
    i = -1
    value.inject(nil) do | representative, ar_object |
      i += 1
      if preloaded_value = @preloaded_records[absolute_vector + ["*#{i}"]]
        build_new_cache_item(preloaded_value, "*", "*#{i}")
      else
        build_new_cache_item(ar_object, "*", "*#{i}")
      end
    end
  else
    build_new_cache_item([], "*", "*")
  end
end
as_hash(children = nil) click to toggle source
# File lib/reactive_record/server_data_cache.rb, line 262
def as_hash(children = nil)
  unless children
    return {} if @ar_object.is_a?(Class) and (@ar_object < ActiveRecord::Base)
    children = [@ar_object.is_a?(BigDecimal) ? @ar_object.to_f : @ar_object]
  end
  if @parent
    if method == "*"
      if @ar_object.is_a? Array  # this happens when a scope is empty there is test case, but
        @parent.as_hash({})      # does it work for all edge cases?
      else
        @parent.as_hash({@ar_object.id => children})
      end
    elsif @ar_object.class < ActiveRecord::Base and children.is_a? Hash
      @parent.as_hash({jsonize(method) => children.merge({
        :id => (method.is_a?(Array) && method.first == "new") ? [nil] : [@ar_object.id],
        @ar_object.class.inheritance_column => [@ar_object[@ar_object.class.inheritance_column]],
        })})
    elsif method == "*all"
      @parent.as_hash({jsonize(method) => children.first})
    else
      @parent.as_hash({jsonize(method) => children})
    end
  else
    {method.name => children}
  end
end
build_new_cache_item(new_ar_object, method, absolute_method) click to toggle source
# File lib/reactive_record/server_data_cache.rb, line 232
def build_new_cache_item(new_ar_object, method, absolute_method)
  new_parent = self
  self.clone.instance_eval do
    @vector = @vector + [method]  # don't push it on since you need a new vector!
    @absolute_vector = @absolute_vector + [absolute_method]
    @ar_object = new_ar_object
    @db_cache << self
    @parent = new_parent
    @root = new_parent.root
    self
  end
end
jsonize(method) click to toggle source
# File lib/reactive_record/server_data_cache.rb, line 255
def jsonize(method)
  # sadly standard json converts {[:foo, nil] => 123} to {"['foo', nil]": 123}
  # luckily [:foo, nil] does convert correctly
  # so we check the methods and force proper conversion
  method.is_a?(Array) ? method.to_json : method
end
method() click to toggle source
# File lib/reactive_record/server_data_cache.rb, line 148
def method
  vector.last
end
value() click to toggle source
# File lib/reactive_record/server_data_cache.rb, line 144
def value
  @ar_object
end