Module: SupportTableCache::RelationOverride Private

Defined in:
lib/support_table_cache/relation_override.rb

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

Instance Method Summary collapse

Instance Method Details

#fetch_by(attributes) ⇒ ActiveRecord::Base?

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.

Same as find_by, but performs a safety check to confirm the query will hit the cache.

Parameters:

  • attributes (Hash)

    Attributes to find the record by.

Returns:

  • (ActiveRecord::Base, nil)

    The found record or nil if not found.

Raises:

  • (ArgumentError)

    if the query cannot use the cache.



64
65
66
67
68
69
70
71
72
73
74
75
76
77
# File 'lib/support_table_cache/relation_override.rb', line 64

def fetch_by(attributes)
  attributes = (attributes || {}).stringify_keys
  query_attributes = support_table_query_attributes(attributes)
  unless SupportTableCache.cacheable_query?(klass, query_attributes)
    raise ArgumentError.new("#{klass.name} does not cache queries by #{(query_attributes || attributes).keys.sort.to_sentence}")
  end
  unless support_table_cacheable_scope?
    raise ArgumentError.new("#{klass.name} cannot cache queries on a relation with conditions that cannot be represented in the cache key")
  end
  if SupportTableCache.open_transaction?(klass)
    raise ArgumentError.new("#{klass.name} cannot cache queries inside a transaction")
  end
  find_by(attributes)
end

#fetch_by!(attributes) ⇒ ActiveRecord::Base

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.

Same as find_by!, but performs a safety check to confirm the query will hit the cache.

Parameters:

  • attributes (Hash)

    Attributes to find the record by.

Returns:

  • (ActiveRecord::Base)

    The found record.

Raises:

  • (ArgumentError)

    if the query cannot use the cache.

  • (ActiveRecord::RecordNotFound)

    if no record is found.



85
86
87
88
89
90
91
# File 'lib/support_table_cache/relation_override.rb', line 85

def fetch_by!(attributes)
  value = fetch_by(attributes)
  if value.nil?
    raise ActiveRecord::RecordNotFound.new("Couldn't find #{klass.name}", klass.name)
  end
  value
end

#find_by(*args) ⇒ ActiveRecord::Base?

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.

Override for the find_by method that looks in the cache first.

Parameters:

  • args (Array<Object>)

    Arguments passed to find_by.

Returns:

  • (ActiveRecord::Base, nil)

    The found record or nil if not found.



11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# File 'lib/support_table_cache/relation_override.rb', line 11

def find_by(*args)
  return super unless klass.include?(SupportTableCache)

  cache = klass.send(:current_support_table_cache)
  return super unless cache

  # Skip caching for has_many or has_many :through associations
  return super if is_a?(ActiveRecord::Associations::CollectionProxy)

  return super if select_values.present?

  # Only queries by simple attribute equality can be matched against cache keys.
  return super unless args.size == 1 && args.first.is_a?(Hash)

  return super unless support_table_cacheable_scope?

  # Queries inside a transaction could see uncommitted data that would be invalid
  # if the transaction is rolled back, so they cannot be cached.
  return super if SupportTableCache.open_transaction?(klass)

  # Apply any conditions from the current relation chain. This returns nil if the relation
  # and the find_by arguments specify different values for the same attribute since both
  # conditions have to be applied by the database in that case.
  attributes = support_table_query_attributes(args.first)
  return super if attributes.nil?

  cache_key = SupportTableCache.cache_key_for_query(klass, attributes)

  if cache_key
    cache.fetch(cache_key, expires_in: support_table_cache_ttl) { super }
  else
    super
  end
end

#find_by!(*args) ⇒ ActiveRecord::Base

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.

Override for the find_by! method that looks in the cache first.

Parameters:

  • args (Array<Object>)

    Arguments passed to find_by!.

Returns:

  • (ActiveRecord::Base)

    The found record.

Raises:

  • (ActiveRecord::RecordNotFound)

    if no record is found.



51
52
53
54
55
56
57
# File 'lib/support_table_cache/relation_override.rb', line 51

def find_by!(*args)
  value = find_by(*args)
  unless value
    raise ActiveRecord::RecordNotFound.new("Couldn't find #{klass.name}", klass.name)
  end
  value
end