Module: CachedCounts::ClassMethods

Defined in:
lib/cached_counts.rb

Instance Method Summary collapse

Instance Method Details

#association_count_key(counter_id, attribute_name, version = 1) ⇒ Object



98
99
100
# File 'lib/cached_counts.rb', line 98

def association_count_key(counter_id, attribute_name, version = 1)
  "#{name}:#{counter_id}:#{attribute_name}_count:#{version}" unless counter_id.nil?
end

#caches_count_of(attribute_name, options = {}) ⇒ Object

Cache the count for an association in memcached.

e.g.

User.caches_count_of :friends
> User.first.friends_count # Users.first.friends.count, but cached

Automatically adds after_commit hooks to the associated class which increment/decrement the value in memcached when needed. Queries the db on cache miss.

Valid options:

:association
  Name of the association to count. Defaults to the attribute_name
  (the required argument to `caches_count_of`).

:alias
  Alias(es) for the count attribute. Useful with join tables.
  e.g. `caches_count_of :user_departments, alias: 'users'`
  > Department.first.users_count

:expires_in
  Expiry for the cached value.

:if
  proc passed through to the after_commit hooks on the counted class;
  decides whether an object counts towards the association total.

:scope
  proc used like an ActiveRecord scope on the counted class on cache misses.

:version
  Cache version - bump if you change the definition of a count.


86
87
88
89
90
91
92
# File 'lib/cached_counts.rb', line 86

def caches_count_of(attribute_name, options = {})
  # Delay actual run to work around circular dependencies
  klass = self
  ActiveSupport.on_load :cached_counts do
    klass.send :caches_count_of!, attribute_name, options
  end
end

#caches_count_where(attribute_name, options = {}) ⇒ Object

Cache the count for a scope in memcached.

e.g.

User.caches_count_where :confirmed
> User.confirmed_count # User.confirmed.count, but cached

Automatically adds after_commit hooks which increment/decrement the value in memcached when needed. Queries the db on cache miss.

Valid options:

:scope
  Name of the scope to count. Defaults to the attribute_name
  (the required argument to `caches_count_where`).

:alias
  Alias(es) for the count attribute.
  e.g. `caches_count_where :confirmed, alias: 'sitemap'`
  > User.sitemap_count

:expires_in
  Expiry for the cached value.

:if
  proc passed through to the after_commit hooks;
  decides whether an object counts towards the association total.

:version
  Cache version - bump if you change the definition of a count.

:race_condition_fallback
  Fallback to the result of this proc if the cache is empty, while
  loading the actual value from the db. Works similarly to
  race_condition_ttl but for empty caches rather than expired values.
  Meant to prevent a thundering-herd scenario, if for example a
  memcached instance goes away. Can be nil; defaults to using a value
  grabbed from the cache or DB at startup.


45
46
47
48
49
50
51
# File 'lib/cached_counts.rb', line 45

def caches_count_where(attribute_name, options = {})
  # Delay actual run to work around circular dependencies
  klass = self
  ActiveSupport.on_load :cached_counts do
    klass.send :caches_count_where!, attribute_name, options
  end
end

#scope_count_key(attribute_name, version = 1) ⇒ Object



94
95
96
# File 'lib/cached_counts.rb', line 94

def scope_count_key(attribute_name, version = 1)
  "#{name}:#{attribute_name}_count:#{version}"
end