Class: AridCache::CacheProxy::ResultProcessor

Inherits:
Object
  • Object
show all
Defined in:
lib/arid_cache/cache_proxy/result_processor.rb

Overview

A class representing a result that is to be processed in some way before being returned to the user.

Provides methods to introspect the result. The contents could be a base type, or an enumerable of sorts…any type really. We are only concerned with enumerables, and especially those containing active records.

TODO: a lot of this logic should be encompassed in the CachedResult. It’s probably a good idea to always cache a CachedResult and move the result-related methods into that class. We have to keep whatever is cached as small as possible tho, so it’s probably best to cache a Hash and load it with CachedResult.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(result, opts = {}) ⇒ ResultProcessor

Returns a new instance of ResultProcessor.



17
18
19
20
# File 'lib/arid_cache/cache_proxy/result_processor.rb', line 17

def initialize(result, opts={})
  @result = result
  @options = opts.is_a?(AridCache::CacheProxy::Options) ? opts : AridCache::CacheProxy::Options.new(opts)
end

Instance Attribute Details

#optionsObject (readonly)

Returns the value of attribute options.



15
16
17
# File 'lib/arid_cache/cache_proxy/result_processor.rb', line 15

def options
  @options
end

Instance Method Details

#is_activerecord?Boolean

Return true if the result is an enumerable and the first item is an active record.

Returns:

  • (Boolean)


45
46
47
# File 'lib/arid_cache/cache_proxy/result_processor.rb', line 45

def is_activerecord?
  AridCache.framework.active_record? && is_enumerable? && @result.first.is_a?(::ActiveRecord::Base)
end

#is_activerecord_reflection?Boolean

Returns:

  • (Boolean)


49
50
51
# File 'lib/arid_cache/cache_proxy/result_processor.rb', line 49

def is_activerecord_reflection?
  AridCache.framework.active_record? && (@result.respond_to?(:proxy_reflection) || @result.respond_to?(:proxy_options) || (AridCache.framework.active_record?(3) && @result.is_a?(::ActiveRecord::Relation)))
end

#is_cached_result?Boolean

Returns:

  • (Boolean)


53
54
55
# File 'lib/arid_cache/cache_proxy/result_processor.rb', line 53

def is_cached_result?
  @result.is_a?(AridCache::CacheProxy::CachedResult)
end

#is_empty?Boolean

Return true if the result is an array and it is empty.

Returns:

  • (Boolean)


23
24
25
# File 'lib/arid_cache/cache_proxy/result_processor.rb', line 23

def is_empty?
  @result.is_a?(Array) && @result.empty?
end

#is_enumerable?Boolean

Return true if the result is an enumerable.

Returns:

  • (Boolean)


28
29
30
# File 'lib/arid_cache/cache_proxy/result_processor.rb', line 28

def is_enumerable?
  @result.is_a?(Enumerable)
end

#is_hashes?Boolean

Return true if the result is a list of hashes

Returns:

  • (Boolean)


33
34
35
# File 'lib/arid_cache/cache_proxy/result_processor.rb', line 33

def is_hashes?
  is_enumerable? && @result.first.is_a?(Hash)
end

#order_in_database?Boolean

Order in the database if an order clause has been specified and we have a list of ActiveRecords or a CachedResult.

Returns:

  • (Boolean)


39
40
41
# File 'lib/arid_cache/cache_proxy/result_processor.rb', line 39

def order_in_database?
  (is_cached_result? && !@options.raw?) || (@options.order_by_key? && is_activerecord?)
end

#to_cacheObject

Return the result to cache. For base types the original result is returned. ActiveRecords return a CachedResult.



59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
# File 'lib/arid_cache/cache_proxy/result_processor.rb', line 59

def to_cache
  # Check if it's an association first, because it doesn't trigger the select if it's
  # a named scope.  Calling respond_to? on an association proxy will trigger a select
  # because it loads up the target and passes the respond_to? on to it.
  @cached =
    if @options.proxy?(:in)
      if is_activerecord_reflection?
        @result = @result.collect { |r| r } # force it to load
      end
      run_user_proxy(:in, @result)
    elsif is_activerecord_reflection? # Don't trigger it unless we really have to
      if @options.count_only?
        lazy_cache.count = @result.count
      else
        lazy_cache.ids = @result.collect { |r| r[:id] }
        lazy_cache.klass = Utilities.collection_klass(@result) || result_klass
        lazy_cache.count = @result.size
      end
      lazy_cache
    elsif is_activerecord?
      lazy_cache.ids = @result.collect { |r| r[:id] }
      lazy_cache.count = @result.size
      lazy_cache.klass = @result.first.class
      lazy_cache
    elsif is_empty? && !AridCache.raw_with_options # deprecated behaviour
      lazy_cache.ids = @result
      lazy_cache.count = 0
      lazy_cache.klass = result_klass
      lazy_cache
    elsif @result.nil? # so we can distinguish a cached nil vs an empty cache
      lazy_cache.klass = NilClass
      lazy_cache
    else
      @result
    end
end

#to_resultObject

Apply any options like pagination or ordering and return the result, which is either some base type, or usually, a list of active records.



98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
# File 'lib/arid_cache/cache_proxy/result_processor.rb', line 98

def to_result  
  if @options.count_only?
    get_count

  elsif @options.proxy?(:out)
    results =
      if @cached.nil? || !@options.raw?
        @result
      else
        @cached
      end
    filtered = filter_results(results)
    # If proxying out, we always have to proxy the result.
    # If proxying both ways, we don't need to proxy the result after seeding the cache.
    if !@options.raw? && (@options[:proxy_out] || @cached.nil?)
      proxy_result = run_user_proxy(:out, filtered)
      if filtered.is_a?(WillPaginate::Collection) && proxy_result.is_a?(Enumerable)
        filtered.replace(proxy_result)
      else
        proxy_result
      end
    else
      filtered
    end

  # If proxying in, we want to return what was stored in the cache, not what was
  # returned by the block.  So with :proxy_in, using :raw => true has no effect.
  elsif @options.proxy?(:in)
    filter_results(@cached || @result)

  elsif (@cached || @result).is_a?(AridCache::CacheProxy::CachedResult) && (@cached || @result).klass == NilClass && !(@cached || @result).has_ids?
    nil

  elsif @options.raw?
    result =
      if @cached.is_a?(AridCache::CacheProxy::CachedResult)
        @cached
      else
        @result
      end
    if @options.deprecated_raw?
      result
    else
      filter_results(result.is_a?(AridCache::CacheProxy::CachedResult) ? result.ids : result)
    end

  elsif is_cached_result?
    fetch_activerecords(filter_results(@result.ids))
  elsif order_in_database?
    fetch_activerecords(filter_results(@result))
  else
    filter_results(@result)
  end
end