Although memcache-client has been abandoned, the author of the gem has written a near drop-in replacement memcached api; dalli. Dalli offers the same api as memcache-client with the benefit of a leaner, faster codebase, written in pure Ruby. For simple model caching, a Rails 3 fork of cache-fu offers a simple acts_as_cached method that automatically caches your active record objects.
To install dalli and cache-fu in your Rails 3 app, simply add the following to your Gemfile and run bundle install.
# Gemfile gem 'dalli' gem 'cache_fu', :git => 'https://github.com/kreetitech/cache_fu.git'
To setup Rails to use the Dalli client for production, add the following to config/environments/production.rb:
# config/environments/production.rb # Enable dalli (memcached) caching config.cache_store = :dalli_store config.action_controller.perform_caching = trueIf you want to cache in any of your other environments, just add the same snippet to your environment of choice.
Dalli can also be used as rack middleware for session caching. To setup session caching with dalli, edit your config/initializers/session_store.rb to contain the following:
# config/initializers/session_store.rb require 'action_dispatch/middleware/session/dalli_store' Rails.application.config.session_store :dalli_store, :memcache_server => '127.0.0.1:11211', :namespace => 'sessions', :key => '_yourappname_session', :expire_after => 30.minutes
Now, whenever you use Rails' built in caching or session storage, dalli will automatically interface with memcached.
Cache-fu requires a little bit of setup too, but there's a rake task to help with configuration:
rake memcached:cache_fu_installThis will write a config/memcached.yml file for configuring model caching. Most of the default settings should be fine, but at the very least, you will have to set the default client to Dalli::client and update the production cache servers. Here's what I have:
# config/memcached.yml defaults: client: Dalli::Client ttl: 1800 readonly: false urlencode: false c_threshold: 10000 compression: true namespace: yourappname benchmarking: false disabled: false debug: false development: servers: 127.0.0.1:11211 # Developers who have memcached installed on their local system should comment the following line # disabled: true test: disabled: true staging: servers: - 127.0.0.1:11211 production: servers: - cache00.mysite.org:11211 - cache01.mysite.org:11211 - cache02.mysite.org:11211
With that, cache-fu should be configured and ready to rock.
Now, it's time to add caching to your models. As an example, let's say I have a blog with a model called posts with attributes title:string, body:text, public:boolean. If I want to cache these posts, I just add the following to my model:
# app/models/post.rb class Post < ActiveRecord::Base acts_as_cached end
This gives your model some special helper methods for caching objects. A good way to use cache-fu is through the use of custom scopes. Basically, you define a scope in the model and then use the "cached" class method to access it via caching in the controller:
# app/model/post.rb def self.recent where('created_at > ?', 1.week.ago).all end # app/controllers/posts_controller.rb def recent_posts @posts = Post.cached(:recent) end
Now, start you memcached server, fire up Rails, and take a look at your console output. If you access an action that uses "cached", you can now see memcached stats in the logger. Notice that the query in the self.recent method contains an all at the end. This is crucial in Rails 3, because otherwise just the relation will be cached and not the returned objects. I've barely scraped the surface of what cache-fu can do, but if you want a more in-depth analysis you can check out this blog post. If I left out any important details or you're having trouble, feel free to leave me a question in the comments.