Conhecendo as opções de cache do Rails 2.1
Leia em 2 minutos
O Ruby on Rails 2.1, dentre outras novidades, trouxe suporte nativo a cache, com diversas opções de armazenamento. O destaque vai para o suporte ao Memcache, de longe uma das opções mais utilizadas. Todas essas novidades foram adicionadas ao módulo ActiveSupport::Cache, que você confere neste artigo.
Configurando as opções de cache
Para definir qual o tipo de cache que você quer utilizar, altere a nova configuração cache_store
, adicionada aos arquivos de ambiente de sua aplicação no diretório config/environments/*.rb. Você pode escolher entre :memory_store
, :file_store
, :mem_cache_store
e drb
.
config.cache_store = :memory_store
config.cache_store = :file_store, '/path/to/cache'
config.cache_store = :mem_cache_store
config.cache_store = :drb_store, "druby://localhost:2250"
config.cache_store = :mem_cache_store, '127.0.0.1:11211', '127.0.0.1:11212', {:namespace => 'myapp'}
A opção padrão de cache é :memory_store
, a menos que o diretório tmp/cache exista; neste caso, a opção utilizada será :file_store
.
Vale lembrar que se você utilizar uma opção cujo ambiente não está funcionando corretamente, sua aplicação não deixará de funcionar. Este comportamento é perfeito para trabalho em equipe, onde um desenvolvedor pode configurar seu ambiente para utilizar o Memcache enquanto os outros não precisam se importar com isso naquele momento.
Como funciona
Todas as funções de cache estão disponíveis no objeto Rails.cache
. Para gravar qualquer coisa no cache você deve utilizar o método write
.
Rails.cache.write('some_identifier', 'some_value')
Você pode passar qualquer valor para ser gravado no cache, incluindo objetos de ActiveRecord.
@user = User.first
Rails.cache.write(@user.cache_key, @user)
O ActiveRecord adiciona um método que gera uma chave única para cada objeto, chamado cache_key
. Este método gera uma chave como "users/1-20080713185825", que você possa acessar e expirar o objeto sempre que precisar. Por padrão, a chave gerada irá utilizar o nome do modelo, o id do objeto e a data de atualização, disponível através do atributo updated_at
.
Para ler um objeto do cache, você pode utilizar o método read
. Ele recebe um único argumento que identifica o objeto. Caso o objeto não seja encontrado, o valor nil
será retornado.
Rails.cache.read('some_identifier')
Você pode verificar se um item existe no cache com o método exist?
.
Rails.cache.exist?('some_identifier')
Você pode estar se perguntando se você precisa utiliza o método exist?
juntamente com read
e write
para acessar um objeto caso ele exista e gravar um novo item caso ele não seja encontrado. Na verdade, você pode utilizar o método fetch
que tenta acessar um item no cache e, caso ele não exista, executa o bloco que é passado e faz a gravação em cache automaticamente.
@users = Rails.cache.fetch('users/all') { User.all }
O método fetch
pode receber um hash de opções. No momento, a única opção disponível é :expires_in
, que permite alterar o tempo de expiração do cache somente para aquele objeto.
@users = Rails.cache.fetch('users/all', :expires_in => 30.minutes) { User.all }
Para o caso de você estar acessando um único objeto, você pode sobrescrever o método cache_key
de modo que ele não gere a chave com o a data de atualização.
class User < ActiveRecord::Base
def cache_key
"users/#{id}"
end
end
Assim, você pode acessar os objetos de maneira mais simples. Veja um exemplo de como isso funcionaria em uma action do controller users.
class UsersControllers < ApplicationController
def show
@user = Rails.cache.fetch("users/#{params[:id]}") { User.find(params[:id]) }
end
end
E se você segue a idéia de encapsular toda a lógica nos modelos, existe sempre a opção de cuidar do cache desta maneira.
class User < ActiveRecord::Base
def self.find_recent_users
Rails.cache.fetch('users/recent') { all :order => 'created_at desc', :limit => 10 }
end
end
Você também pode remover qualquer item do cache com o método delete
, que retorna true
or false
.
Rails.cache.delete('users/1')
Finalizando
É isso! Acredito que este artigo cubra as principais funcionalidades de cache que foram adicionadas à versão 2.1. Dúvidas, sugestões ou correções, envie um comentário!