Share This Article
To implement a cache in Rails, you can use the ActiveSupport::Cache
class.
The ActiveSupport::Cache class provides a unified API for a variety of caching backends.
For example:
- Memory store
- File store
- Dalli store
You can use the ActiveSupport::Cache::Store#fetch
method to read from the cache.
If the data is not in the cache, the block you pass to the fetch
method will be executed, and the result will be stored in the cache.
require "active_support/cache"
store = ActiveSupport::Cache::MemoryStore.new
# or
# store = ActiveSupport::Cache::FileStore.new("/path/to/cache/directory")
# store data in the cache
store.write("some_key", "some data")
# read data from the cache
store.read("some_key")
# "some data"
# read data from the cache, but if it's not there then execute the block
# & store the result in the cache
store.fetch("some_key") do
"some data"
end
# "some data"
# delete data from the cache
store.delete("some_key")
You can read more about the ActiveSupport::Cache
API in the Rails API docs.
The Cache Key
When using the cache, you need to generate a cache key.
This cache key should be unique for each combination of data you want to store in the cache.
For example, if you are caching the results of a SQL query, the cache key should be unique for each SQL query.
You can use ActiveSupport::Cache::Store#generate_unique_key
to generate a unique cache key.
Cache expiration
When using the fetch
method, you can specify the cache’s expiration time.
For example:
# cache data for 1 hour
store.fetch("some_key", expires_in: 1.hour) do
"some data"
end
# cache data forever
store.fetch("some_key", expires_in: nil) do
"some data"
end
If you are using the write
method, you can also specify an expiration time.
For example:
# cache data for 1 hour
store.write("some_key", "some data", expires_in: 1.hour)
# cache data forever
store.write("some_key", "some data", expires_in: nil)
You can also use the `expires_at` option instead of expires_in
.
# cache data until a specific time
store.fetch("some_key", expires_at: 1.hour.from_now) do
"some data"
end
Note: The time you specify is in seconds, so if you want to expire the cache in 1 hour, you need to use the 1.hour
shortcut.
If you want more control over cache expiration, you can use the ActiveSupport::Cache::Store#Touch
method.
This method will update the cache key with the new expiration time, but it will not update the data in the cache.
For example:
# cache data forever
store.write("some_key", "some data", expires_in: nil)
# update the expiration time
store.touch("some_key", expires_in: 1.hour)
If the data in the cache is stale, you can use the ActiveSupport::Cache::Store#read_multi
method to read multiple keys from the cache in one operation.
This method will return an array of data for the given keys.
If a cache key does not exist, then nil
will be returned for that key.
Cache Fetching
If you want to read multiple keys from the cache and you want to use a block to generate the data for the missing keys, you can use the ActiveSupport::Cache::Store#fetch_multi
method.
This method is similar to the fetch
method but takes an array of keys as an argument.
# cache data forever
store.write("key1", "data1", expires_in: nil)
store.write("key2", "data2", expires_in: nil)
# read multiple keys from the cache
store.read_multi("key1", "key2", "key3")
# ["data1", "data2", nil]
# read multiple keys from the cache, but if they are not in the cache
# then execute the block and store the result in the cache
store.fetch_multi("key1", "key2", "key3") do |key|
"data for #{key}"
end
# ["data1", "data2", "data for key3"]
# delete multiple keys from the cache
store.delete_multi("key1", "key2")
Note: The fetch_multi
method is not supported by all cache backends.
Rails.cache
Rails provides a global cache object that you can use to store data in the cache.
The global cache object is an instance of the ActiveSupport::Cache::MemoryStore
class.
You can use the Rails.cache
object like this:
# store data in the cache
Rails.cache.write("some_key", "some data")
# read data from the cache
Rails.cache.read("some_key")
# "some data"
# delete data from the cache
Rails.cache.delete("some_key")
You can also use the Rails.cache
object in your templates.
For example:
<% # store data in the cache %>
<% cache "some_key" do %>
some data
<% end %>
<% # read data from the cache %>
<%= cache "some_key" do %>
some data
<% end %>
<% # delete data from the cache %>
<%= cache.delete("some_key") %>
If you want to use a different caching backend, you need to set the config.cache_store
option in your config/environments/production.rb
file.
For example:
Rails.application.configure do
# ...
config.cache_store = :memory_store
# ...
end
You can read more about caching in the Ruby on Rails Guides.
Summary
In this article, you’ve learned how to use the ActiveSupport::Cache
class to implement a cache in a Ruby on Rails application.
You’ve also learned how to use the Rails.cache
object to store data in the cache.