その他
    ホーム技術発信DoRuby【Rails】I18nの言語データをDBから取得 / キャッシュ使用【i18n/i18n-active_record】

    【Rails】I18nの言語データをDBから取得 / キャッシュ使用【i18n/i18n-active_record】

    この記事はアピリッツの技術ブログ「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