Gutter Press has a bunch of settings I want to store in the database and edit through a management interface, but I don't want to be retrieved on each request. These are things like titles and menu items. I'm used to Rail's page caching, but this is the first time I've directly used Rail's caching mechanism directly. It's very easy.
In this case, I have a model object (but it doesn't have to be) which holds all my site settings.
I define a key and use that to interact with Rails.cache. When a key is changed, the cache is invalidated by deleting it. Super simple.
class SiteSetting < ApplicationRecord
# <-------- model methods, stripped out for brevity
# Cache key for storing all settings in Rails.cache
CACHE_KEY = 'site_settings_all'.freeze
# Default settings - these are used as fallbacks when no database record exists
DEFAULTS = {
'site_name' => 'Gutter Press',
'site_description' => 'A modern blogging platform',
'site_tagline' => 'Share your stories with the world',
# etc
}.freeze
# Class method to get a setting value with caching
def self.get(key)
# First try to get from cache
all_settings = Rails.cache.fetch(CACHE_KEY, expires_in: 1.hour) do
# Cache miss - load all settings from database
pluck(:key, :value).to_h
end
# Return cached value or fall back to default
all_settings[key.to_s] || DEFAULTS[key.to_s]
end
# Class method to set a setting value and invalidate cache
def self.set(key, value)
setting = find_or_initialize_by(key: key.to_s)
setting.value = value.to_s
if setting.save
# Invalidate the cache so next request will reload from database
Rails.cache.delete(CACHE_KEY)
value
else
false
end
end
end