Class: ReactiveRecord::ServerDataCache

Inherits:
Object
  • Object
show all
Defined in:
lib/reactive_record/server_data_cache.rb

Defined Under Namespace

Classes: CacheItem

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(acting_user, preloaded_records) ⇒ ServerDataCache

Returns a new instance of ServerDataCache.



90
91
92
93
94
95
# File 'lib/reactive_record/server_data_cache.rb', line 90

def initialize(acting_user, preloaded_records)
  @acting_user = acting_user
  @cache = []
  @requested_cache_items = []
  @preloaded_records = preloaded_records
end

Class Method Details

.[](models, associations, vectors, acting_user) ⇒ Object



108
109
110
111
112
113
114
115
116
117
118
# File 'lib/reactive_record/server_data_cache.rb', line 108

def self.[](models, associations, vectors, acting_user)
  ActiveRecord::Base.public_columns_hash
  result = nil
  ActiveRecord::Base.transaction do
    cache = new(acting_user, ReactiveRecord::Base.save_records(models, associations, acting_user, false, false))
    vectors.each { |vector| cache[*vector] }
    result = cache.as_json
    raise ActiveRecord::Rollback
  end
  result
end

.load_from_json(tree, target = nil) ⇒ Object



293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
# File 'lib/reactive_record/server_data_cache.rb', line 293

def self.load_from_json(tree, target = nil)
  ignore_all = nil

  # have to process *all before any other items
  # we leave the "*all" key in just for debugging purposes, and then skip it below

  if sorted_collection = tree["*all"]
    target.replace sorted_collection.collect { |id| target.proxy_association.klass.find(id) }
  end

  if id_value = tree["id"] and id_value.is_a? Array
    target.id = id_value.first
  end
  tree.each do |method, value|
    method = JSON.parse(method) rescue method
    new_target = nil
    if method == "*all"
      next # its already been processed above
    elsif !target
      load_from_json(value, Object.const_get(method))
    elsif method == "*count"
      target.set_count_state(value.first)
    elsif method.is_a? Integer or method =~ /^[0-9]+$/
      new_target = target.push_and_update_belongs_to(method)
      #target << (new_target = target.proxy_association.klass.find(method))
    elsif method.is_a? Array
      if method[0] == "new"
        new_target = ReactiveRecord::Base.find_by_object_id(target.base_class, method[1])
      elsif !(target.class < ActiveRecord::Base)
        new_target = target.send *method
        # value is an array if scope returns nil, so we destroy the bogus record
        new_target.destroy and new_target = nil if value.is_a? Array
      else
        target.backing_record.update_attribute([method], target.backing_record.convert(method, value.first))
      end
    elsif target.class.respond_to?(:reflect_on_aggregation) and aggregation = target.class.reflect_on_aggregation(method) and
    !(aggregation.klass < ActiveRecord::Base)
      target.send "#{method}=", aggregation.deserialize(value.first)
    elsif value.is_a? Array
      target.send "#{method}=", value.first unless method == "id" # we handle ids first so things sync nicely
    elsif value.is_a? Hash and value[:id] and value[:id].first and association = target.class.reflect_on_association(method)
      # not sure if its necessary to check the id above... is it possible to for the method to be an association but not have an id?
      new_target = association.klass.find(value[:id].first)
      target.send "#{method}=", new_target
    elsif !(target.class < ActiveRecord::Base)
      new_target = target.send *method
      # value is an array if scope returns nil, so we destroy the bogus record
      new_target.destroy and new_target = nil if value.is_a? Array
    else
      new_target = target.send("#{method}=", target.send(method))
    end
    load_from_json(value, new_target) if new_target
  end
end

Instance Method Details

#[](*vector) ⇒ Object



99
100
101
102
103
104
105
106
# File 'lib/reactive_record/server_data_cache.rb', line 99

def [](*vector)
  root = CacheItem.new(@cache, @acting_user, vector[0], @preloaded_records)
  vector[1..-1].inject(root) { |cache_item, method| cache_item.apply_method method if cache_item }
  vector[0] = vector[0].constantize
  new_items = @cache.select { | cache_item | cache_item.root == root }
  @requested_cache_items += new_items
  new_items.last.value if new_items.last
end

#as_jsonObject



124
125
126
127
128
# File 'lib/reactive_record/server_data_cache.rb', line 124

def as_json
  @requested_cache_items.inject({}) do | hash, cache_item|
    hash.deep_merge! cache_item.as_hash
  end
end

#clear_requestsObject



120
121
122
# File 'lib/reactive_record/server_data_cache.rb', line 120

def clear_requests
  @requested_cache_items = []
end

#detect(&block) ⇒ Object



132
# File 'lib/reactive_record/server_data_cache.rb', line 132

def detect(&block); @cache.detect &block; end

#inject(initial, &block) ⇒ Object



134
# File 'lib/reactive_record/server_data_cache.rb', line 134

def inject(initial, &block); @cache.inject(initial) &block; end

#select(&block) ⇒ Object



130
# File 'lib/reactive_record/server_data_cache.rb', line 130

def select(&block); @cache.select &block; end