Skip to content

Instantly share code, notes, and snippets.

@bogn
Last active January 4, 2016 09:09
Show Gist options
  • Save bogn/8600648 to your computer and use it in GitHub Desktop.
Save bogn/8600648 to your computer and use it in GitHub Desktop.
Naming is hard
module Models
module GroupByCaching
extend ActiveSupport::Concern
included do
CACHE_KEY_PREFIX = "#{self.name.collectionize}_grouped_by"
end
module ClassMethods
# Loads all documents, groups them by the given key and puts them in the cache if there is none yet.
# @param [Symbol, String] group_by_key the key that will determine the values of the returned hash
# @param [Hash] caching_config is passed to the concrete ActiveSupport::Cache::Store. See the latter for a detailed description
# @option caching_config [Numeric] :expires_in sets an expiration time in seconds for the cache entry when it will be automatically removed from the cache.
# @option caching_config [Numeric] :race_condition_ttl sets the number of seconds that an expired entry can be reused while a new value is being regenerated.
# @return [Hash] with the keys being the results for the given key, mapped to the loaded documents having that value
def cache_all_grouped_by(group_by_key, caching_config)
caching_config.assert_valid_keys(ActiveSupport::Cache::UNIVERSAL_OPTIONS)
cache_key = get_cache_key(group_by_key)
Rails.cache.fetch(cache_key, caching_config) do
all.group_by(&group_by_key)
end
end
# @param [Symbol, String] field of the document that is used to get a cached set
# @param [Object] value for #field that is used to retrieve the documents from the cache
# @return [Array<Mongoid::Document>] the cached mongoid documents for the given #value
def cached_for(field, value)
cache_key = get_cache_key(field)
Rails.cache.read(cache_key)[value] || []
end
private
def get_cache_key(field)
"#{CACHE_KEY_PREFIX}_#{field}"
end
end
end
end
# Caching all items so we can prevent an items query for each group
caching_config = {
expires_in: 30.seconds, # the whole export shouldn't take that long
race_condition_ttl: 10.seconds # @see ActiveSupport::Cache::Store
}
Item.cache_all_grouped_by(:group_id, caching_config)
@bogn
Copy link
Author

bogn commented Jan 24, 2014

Item.cached_for_group(group.id) is a good suggestion.

@bogn
Copy link
Author

bogn commented Jan 24, 2014

cached_for_group it is.

@bogn
Copy link
Author

bogn commented Jan 24, 2014

Made the model concern more general.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment