-
-
Save andreimaxim/41bfdc5e501fcd1d3870f02989dac9ce to your computer and use it in GitHub Desktop.
Override cache key and touch methods in active record when we cannot update the last modified / updated at column in database. We keep track of the changes in memcache.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module CacheKeyMonkeyPatch | |
module ActiveRecord | |
module Integration | |
# Returns a cache key that can be used to identify this record. | |
# | |
# ==== Examples | |
# | |
# Product.new.cache_key # => "products/new" | |
# Product.find(5).cache_key # => "products/5" (updated_at / last_modified_time not available) | |
# Person.find(5).cache_key # => "people/5-20140227181414671756000" (updated_at / last_modified_time available) | |
def cache_key | |
last_update_timestamp = Rails.cache.read(object_key) | |
return "#{self.class.model_name.cache_key}/#{id}-#{last_update_timestamp}" if last_update_timestamp | |
case | |
when new_record? | |
cached_cache_key = "#{self.class.model_name.cache_key}/new" | |
when timestamp = (self[:updated_at] || self.respond_to?(:last_modified_time) && self.last_modified_time) | |
timestamp = timestamp.to_s(:nsec) | |
Rails.logger.info "\e[33m READ: #{object_key} from nil to #{timestamp}" | |
Rails.cache.write(object_key, timestamp) | |
cached_cache_key = "#{self.class.model_name.cache_key}/#{id}-#{timestamp}" | |
else | |
cached_cache_key = "#{self.class.model_name.cache_key}/#{id}" | |
end | |
cached_cache_key | |
end | |
end | |
end | |
end | |
ActiveRecord::Base.class_eval do | |
include CacheKeyMonkeyPatch::ActiveRecord::Integration | |
end | |
module ActiveRecord | |
class Base | |
def update_cache_key_for_associated_belongs_to_models(event) | |
belongs_to_associations_to_touch = self.class.reflect_on_all_associations(:belongs_to).select { |assoc| assoc.options[:touch] } | |
belongs_to_associations_to_touch.each do |belongs_to_assoc| | |
associated_object = self.send(belongs_to_assoc.name) | |
associated_object.touch("PROPAGATE from #{self.class.to_s}") if associated_object | |
end | |
end | |
def touch(event = nil) | |
event ||= 'CREATE' | |
cached_timestamp = Rails.cache.fetch(object_key) || 'nil' | |
new_timestamp = Time.zone.now.to_s(:nsec) | |
Rails.logger.info "\e[33m #{event} #{object_key} from #{cached_timestamp} to #{new_timestamp}" | |
Rails.cache.write(object_key, new_timestamp) | |
update_cache_key_for_associated_belongs_to_models(event) | |
end | |
def object_key | |
"cache_key_#{self.class.model_name.i18n_key}_#{self.id}" | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment