Skip to content

Instantly share code, notes, and snippets.

@wheeyls
Last active May 15, 2022 07:04
Show Gist options
  • Save wheeyls/5650947 to your computer and use it in GitHub Desktop.
Save wheeyls/5650947 to your computer and use it in GitHub Desktop.
A cached key-value store backend for Rails I18n. Designed to speed up translations when using a database like Redis or Mongo.
class ApplicationController < ActionController::Base
before_filter :ensure_fresh_i18n
private
def ensure_fresh_i18n
I18n.backend.ensure_freshness! I18n.locale
end
end
module I18n
module Backend
class CachedKeyValueStore < KeyValue
include Memoize
KEY_PREFIX = 'i18n:locale_version:'
def store_translations(locale, data, options = {})
update_version! locale
super
end
def ensure_freshness!(locale)
current = current_version locale
if last_version[locale] != current
reset_memoizations! locale
last_version[locale] = current
end
end
def last_version
@last_version ||= {}
end
def update_version!(locale)
@store["#{KEY_PREFIX}#{locale}"] = Time.now.to_i
end
def current_version(locale)
@store["#{KEY_PREFIX}#{locale}"]
end
end
end
end
require 'spec_helper'
describe I18n::Backend::CachedKeyValueStore do
let(:store) { {} }
subject { I18n::Backend::CachedKeyValueStore.new(store) }
describe '#ensure_freshness!' do
context 'with expired locale' do
before do
store['i18n:locale_version:en'] = '2'
end
it 'calls reset_memoizations!' do
subject.should_receive(:reset_memoizations!).with(:en)
subject.ensure_freshness! :en
end
it 'updates last_locale' do
subject.ensure_freshness! :en
subject.last_version.should == { en: '2' }
end
end
context 'with current locale' do
before do
store['i18n:locale_version:en'] = '1'
subject.last_version[:en] = '1'
end
it 'does not call reset_memoizations!' do
subject.should_not_receive(:reset_memoizations!)
subject.ensure_freshness! :en
end
it 'maintains last_locale' do
subject.ensure_freshness! :en
subject.last_version.should == { en: '1' }
end
end
end
describe 'store_translations' do
before do
store['i18n:locale_version:en'] = '2'
end
it 'updates and dememoizes' do
subject.should_receive(:reset_memoizations!).with(:en)
subject.store_translations(:en, {simple: 'test'})
subject.current_version(:en).should_not == '2'
store['en.simple'].should match(/test/)
end
end
end
I18n.backend = I18n::Backend::CachedKeyValueStore.new($redis)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment