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.