Module: SupportTableCache

Extended by:
ActiveSupport::Concern
Defined in:
lib/support_table_cache.rb,
lib/support_table_cache/associations.rb,
lib/support_table_cache/fiber_locals.rb,
lib/support_table_cache/memory_cache.rb,
lib/support_table_cache/find_by_override.rb,
lib/support_table_cache/relation_override.rb

Overview

This concern can be added to a model to add the ability to look up entries in the table using Rails.cache when calling find_by rather than hitting the database every time.

Defined Under Namespace

Modules: Associations, ClassMethods, FindByOverride, RelationOverride Classes: FiberLocals, MemoryCache

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.cacheActiveSupport::Cache::Store

Get the global cache (will default to Rails.cache if running in a Rails environment).

Returns:

  • (ActiveSupport::Cache::Store)


192
193
194
195
196
197
198
199
200
# File 'lib/support_table_cache.rb', line 192

def cache
  if testing_cache
    testing_cache
  elsif @cache != NOT_SET
    @cache
  elsif defined?(Rails.cache)
    Rails.cache
  end
end

.cache=(value) ⇒ void

This method returns an undefined value.

Set the global cache to use.

Parameters:

  • value (ActiveSupport::Cache::Store, Symbol)

    The cache instance to use. You can also specify the value :memory to use an optimized in-memory cache.



184
185
186
187
# File 'lib/support_table_cache.rb', line 184

def cache=(value)
  value = MemoryCache.new if value == :memory
  @cache = value
end

.cache_key(klass, attributes, key_attribute_names, case_sensitive) ⇒ Array(String, Hash)?

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Generate a consistent cache key for a set of attributes. It will return nil if the attributes are not cacheable.

Parameters:

  • klass (Class)

    The class that is being cached.

  • attributes (Hash)

    The attributes used to find a record.

  • key_attribute_names (Array<String>)

    List of attributes that can be used as a key in the cache.

  • case_sensitive (Boolean)

    Indicator if string values are case-sensitive in the cache key.

Returns:

  • (Array(String, Hash), nil)

    A two-element array with the class name and attributes hash, or nil if not cacheable.



236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
# File 'lib/support_table_cache.rb', line 236

def cache_key(klass, attributes, key_attribute_names, case_sensitive)
  return nil if attributes.blank? || key_attribute_names.blank?

  sorted_names = attributes.keys.map(&:to_s).sort
  return nil unless sorted_names == key_attribute_names

  sorted_attributes = {}
  sorted_names.each do |attribute_name|
    value = (attributes[attribute_name] || attributes[attribute_name.to_sym])
    if !case_sensitive && (value.is_a?(String) || value.is_a?(Symbol))
      value = value.to_s.downcase
    end
    sorted_attributes[attribute_name] = value
  end

  [klass.name, sorted_attributes]
end

.disable(disabled = true) { ... } ⇒ Object?

Disable the caching behavior for all classes. If a block is specified, then caching is only disabled for that block. If no block is specified, then caching is disabled globally.

Parameters:

  • disabled (Boolean) (defaults to: true)

    Caching will be disabled if this is true and enabled if false.

Yields:

  • Executes the provided block with caching disabled or enabled (if block is given).

Returns:

  • (Object, nil)

    The return value of the block if a block is given, nil otherwise.



152
153
154
155
156
157
158
# File 'lib/support_table_cache.rb', line 152

def disable(disabled = true, &block)
  if block
    SupportTableCache.with_fiber_local("support_table_cache_disabled", !!disabled, &block)
  else
    @disabled = !!disabled
  end
end

.disabled?Boolean

Return true if caching has been disabled.

Returns:

  • (Boolean)


171
172
173
174
175
176
177
178
# File 'lib/support_table_cache.rb', line 171

def disabled?
  block_value = SupportTableCache.fiber_local_value("support_table_cache_disabled")
  if block_value.nil?
    !!@disabled
  else
    block_value
  end
end

.enable { ... } ⇒ Object?

Enable the caching behavior for all classes. If a block is specified, then caching is only enabled for that block. If no block is specified, then caching is enabled globally.

Yields:

  • Executes the provided block with caching enabled (if block is given).

Returns:

  • (Object, nil)

    The return value of the block if a block is given, nil otherwise.



165
166
167
# File 'lib/support_table_cache.rb', line 165

def enable(&block)
  disable(false, &block)
end

.fiber_local_value(varname) ⇒ Object



254
255
256
# File 'lib/support_table_cache.rb', line 254

def fiber_local_value(varname)
  @fiber_locals[varname]
end

.testing! { ... } ⇒ Object

Enter test mode for a block. New caches will be used within each test mode block. You can use this to wrap your test methods so that cached values from one test don’t show up in subsequent tests.

Yields:

  • Executes the provided block in test mode.

Returns:

  • (Object)

    The return value of the block.



208
209
210
211
212
213
214
215
# File 'lib/support_table_cache.rb', line 208

def testing!(&block)
  save_val = SupportTableCache.fiber_local_value("support_table_cache_test_cache")
  if save_val.nil?
    SupportTableCache.with_fiber_local("support_table_cache_test_cache", MemoryCache.new, &block)
  else
    yield
  end
end

.testing_cacheSupportTableCache::MemoryCache?

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Get the current test mode cache. This will only return a value inside of a testing! block.

Returns:



221
222
223
224
225
# File 'lib/support_table_cache.rb', line 221

def testing_cache
  return nil if @cache.nil?

  SupportTableCache.fiber_local_value("support_table_cache_test_cache")
end

.with_fiber_local(varname, value, &block) ⇒ Object



258
259
260
# File 'lib/support_table_cache.rb', line 258

def with_fiber_local(varname, value, &block)
  @fiber_locals.with(varname, value, &block)
end

Instance Method Details

#uncachevoid

This method returns an undefined value.

Remove the cache entry for this record.



266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
# File 'lib/support_table_cache.rb', line 266

def uncache
  cache_by_attributes = self.class.support_table_cache_by_attributes
  return if cache_by_attributes.blank?

  cache = self.class.send(:current_support_table_cache)
  return if cache.nil?

  cache_by_attributes.each do |attribute_names, case_sensitive|
    attributes = {}
    attribute_names.each do |name|
      attributes[name] = self[name]
    end
    cache_key = SupportTableCache.cache_key(self.class, attributes, attribute_names, case_sensitive)
    cache.delete(cache_key)
  end
end