Cached Models
CachedModels provides to your models a transparent approach to use ActiveSupport cache mechanism.
Usually, when you decide to use cache for your ActiveRecord results, you have to manually implement complex expiring policies, like the following:
1 class Author < ActiveRecord::Base 2 has_many :posts 3 4 after_save :expire_cache 5 6 def cached_posts 7 Rails.cache.fetch("#{cache_key}/posts") { self.posts } 8 end 9 10 private 11 def expire_cache 12 Rails.cache.delete("#{cache_key}/posts") 13 end 14 end 15 16 class Post < ActiveRecord::Base 17 belongs_to :author 18 19 after_save :expire_cache 20 21 private 22 def expire_cache 23 Rails.cache.delete("#{author.cache_key}/posts") 24 end 25 end
The problem with this kind of approach is that the code complexity grows on the cached-stuff growing.
If I would to add hasmany :recentposts and cache the results, I should write other bureaucracy code, for observing my objects.
Note that the above code is incomplete, because doesn't handles a lot of cased provided by the has_many macro. For instance:
1 post = author.posts.last 2 another_author.posts << post
The second instruction should expire caches for both the models, cache values are now inconsistent. This means, of course, write other code and add code complexity.
Solution
It would be nice to DRYup your caching code. Here the cached_models approach:
1 class Author < ActiveRecord::Base 2 has_many :posts, :cached => true 3 end 4 5 class Post < ActiveRecord::Base 6 belongs_to :author, :cached => true 7 end
That's all!!.
A more complex example..
1 class Project < ActiveRecord::Base 2 has_many :developers, :cached => true 3 4 has_many :tickets, :cached => true 5 has_many :recent_tickets, :limit => 5, 6 :order => 'id DESC', :cached => true 7 end 8 9 class Developer < ActiveRecord::Base 10 belongs_to :project, :cached => true 11 end
Example 1
1 project.developers # Database fetch and automatic cache storing 2 3 developer = project.developers.last 4 developer.update_attributes :first_name => 'Luca' # Database update and cache expiration for project cache
Example 2
1 # Fetch associated collection for both the projects 2 project.developers 3 project2.developers 4 5 developer = project.developers.last 6 project2.developers << developer # Database update and cache renewal for both project and project2 caches
Example 3
1 project.tickets # Database fetch and automatic cache storing 2 ticket = project.recent_tickets.first 3 ticket.update_attributes :state => 'solved' # Database update and cache expiration for both tickets and recent_tickets entries
Installation
There are three ways to install CachedModels:
Gemified Rails plugin
1 #config/environment.rb 2 Rails::Initializer.run do |config| 3 config.gem 'cached-models' 4 end
1 $ (sudo) rake gems:install 2 $ rake gems:unpack
Rails plugin
1 $ ./script/plugin install git://github.com/jodosha/cached-models.git
Standalone
1 $ (sudo) gem install cached-models
1 require 'rubygems' 2 require 'activerecord' 3 require 'cached-models' 4 5 ActiveRecord::Base.rails_cache = ActiveSupport::Cache.lookup_store(:mem_cache_store, 'localhost')
Issues
The current version works only with the has_many macro.
Make sure to configure your current environment with:
1 config.cache_classes = true 2 config.action_controller.perform_caching = true 3 config.cache_store = :mem_cache_store
Repository
http://github.com/jodosha/cached-models/tree/master
How to contribute
-
Check out the code and test it:
1 $ ./script/plugin install git://github.com/jodosha/cached-models.git
- Create a ticket to the Sushistar Lighthouse page
- Create a patch and add as attachment to the ticket.
advertising




