Module: SupportTableCache

Extended by:
ActiveSupport::Concern
Defined in:
lib/support_table_cache.rb,
lib/support_table_cache/associations.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: 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)


197
198
199
200
201
202
203
204
205
# File 'lib/support_table_cache.rb', line 197

def cache
  if testing_cache
    testing_cache
  elsif defined?(@cache)
    @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.



189
190
191
192
# File 'lib/support_table_cache.rb', line 189

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.



244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
# File 'lib/support_table_cache.rb', line 244

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.



151
152
153
154
155
156
157
158
159
160
161
162
163
# File 'lib/support_table_cache.rb', line 151

def disable(disabled = true, &block)
  if block
    save_val = Thread.current.thread_variable_get(:support_table_cache_disabled)
    begin
      Thread.current.thread_variable_set(:support_table_cache_disabled, !!disabled)
      yield
    ensure
      Thread.current.thread_variable_set(:support_table_cache_disabled, save_val)
    end
  else
    @disabled = !!disabled
  end
end

.disabled?Boolean

Return true if caching has been disabled.

Returns:

  • (Boolean)


176
177
178
179
180
181
182
183
# File 'lib/support_table_cache.rb', line 176

def disabled?
  block_value = Thread.current.thread_variable_get(:support_table_cache_disabled)
  if block_value.nil?
    !!(defined?(@disabled) && @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.



170
171
172
# File 'lib/support_table_cache.rb', line 170

def enable(&block)
  disable(false, &block)
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.



213
214
215
216
217
218
219
220
221
222
223
# File 'lib/support_table_cache.rb', line 213

def testing!(&block)
  save_val = Thread.current.thread_variable_get(:support_table_cache_test_cache)
  if save_val.nil?
    Thread.current.thread_variable_set(:support_table_cache_test_cache, MemoryCache.new)
  end
  begin
    yield
  ensure
    Thread.current.thread_variable_set(:support_table_cache_test_cache, save_val)
  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:



229
230
231
232
233
# File 'lib/support_table_cache.rb', line 229

def testing_cache
  unless defined?(@cache) && @cache.nil?
    Thread.current.thread_variable_get(:support_table_cache_test_cache)
  end
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