この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。
前回「I18nの言語データをDBから取得」では毎回DBアクセスが走りパフォーマンスに不安があるためキャッシュを使用する方法を記述します。
3.config/initializers/i18n/cacheable.rb
の作成
i18nのオープンクラスを使用
module I18n
module Base
def translate(*args)
options = args.last.is_a?(Hash) ? args.pop.dup : {}
key = args.shift
backend = config.backend
locale = options.delete(:locale) || config.locale
handling = options.delete(:throw) && :throw || options.delete(:raise) && :raise # TODO: deprecate :raise
translate_result(key, backend, locale, handling, options)
end
alias t translate
def translate_result(key, backend, locale, handling, options)
cache_key = translate_cache_key(locale, key, options)
# キャッシュから取得orキャッシュを作成
Rails.cache.fetch(cache_key) do
enforce_available_locales!(locale)
result = catch(:exception) do
if key.is_a?(Array)
key.map { |k| backend.translate(locale, k, options) }
else
backend.translate(locale, key, options)
end
end
result.is_a?(MissingTranslation) ? handle_exception(handling, result, locale, key, options) : result
end
end
def translate_cache_key(locale, key, options = {})
File.join(locale.to_s, key.to_s, options.presence.to_s)
end
end
end
3.config/initializers/translation/cacheable.rb
の作成
レコードとキャッシュを一緒に作成、更新、削除する
Translation.class_eval do
after_create :create_i18n_translate_cache
after_destroy :delete_i18n_translate_cache
after_update :reset_i18n_translate_cache
private
def create_i18n_translate_cache
I18n.t(key, locale: locale) # 一回呼んでキャッシュ作成
end
def delete_i18n_translate_cache
Rails.cache.delete(delete_cache_key)
end
def reset_i18n_translate_cache
delete_i18n_translate_cache
create_i18n_translate_cache
end
def delete_cache_key
I18n.translate_cache_key(locale_was, key_was)
end
end