├── init.rb ├── lib └── cacheable_hash.rb └── README /init.rb: -------------------------------------------------------------------------------- 1 | require 'cacheable_hash' -------------------------------------------------------------------------------- /lib/cacheable_hash.rb: -------------------------------------------------------------------------------- 1 | class CacheableHash 2 | attr_accessor :cache_key, :expires_in, :hash 3 | 4 | def initialize(cache_key, *args) 5 | options = args.extract_options! 6 | 7 | self.cache_key = cache_key 8 | self.expires_in = (options[:expires_in] || 6.hours) 9 | 10 | self.hash = Hash.new 11 | if !options[:hash].blank? 12 | options[:hash].each_pair do |key, value| 13 | self.hash[key.to_sym] = value 14 | end 15 | end 16 | end 17 | 18 | def method_missing(sym, *args, &block) 19 | return_value = hash.send(sym, *args, &block) 20 | Rails.cache.write(self.cache_key, self, :expires_in => self.expires_in) unless sym.to_s == '[]' 21 | 22 | return return_value 23 | end 24 | end -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | Plugin Details 2 | -------------- 3 | Rails.cache freezes values in hashes that are cached directly. CacheableHash is a wrapper for Hash objects that prevents that from happening. Changes to the Hash being wrapped are automatically persisted back to the cache store so that everything stays in sync. 4 | 5 | Example 6 | ------- 7 | An instance of CacheableHash is used like any other hash. A cache key is the only thing required. 8 | 9 | >> fruit = CacheableHash.new('fruit_hash_key', :hash => {:apple => 'red', :banana => 'yellow'}, :expires_in => 1.week) 10 | >> fruit[:banana] 11 | => "yellow" 12 | 13 | Changes are automatically persisted. 14 | 15 | >> fruit = Rails.cache.read('fruit_hash_key') 16 | >> fruit[:apple] 17 | => "red" 18 | 19 | >> fruit[:apple] = 'green' 20 | 21 | >> Rails.cache.read('fruit_hash_key')[:apple] 22 | => "green" 23 | 24 | About Synchronicity 25 | ------------------- 26 | Whenever a method is called on an instance of CacheableHash, that instance automatically writes itself back to the cache store. Often, this is unnecessary. If you call .keys, for example, there is no reason to write back to the cache store. Only when reading a value from the hash using [], is the copy in the cache store not specifically updated. But, rather than worrying about the specific methods that change the contents of the hash, it's safer to just update the instance in the cache store whenever not specifically reading values. 27 | 28 | License 29 | ------- 30 | This plugin is available under the MIT license. 31 | 32 | Authors 33 | ------- 34 | Thomas Mango 35 | http://slicedsoftware.com 36 | --------------------------------------------------------------------------------