2016-08-23 5 views
7

У меня есть система перевода на базе базы данных для моего приложения Rails, которое отлично работает, за исключением того факта, что он, очевидно, отправляет много запросов в базу данных. Я могу использовать кеш только для определенного количества запросов, но подходящим вариантом для меня является экспорт таблицы перевода в YAML-файл, который может быть прочитан системой.Внешний локальный путь I18n (AWS)

Проблема у меня в том, что мое приложение находится на Heroku, и вы не можете писать в эту файловую систему, я должен использовать AWS (используя Carrierwave) для хранения локальных файлов. Я могу писать в AWS, но я не могу заставить приложение Rails читать локальные файлы из своего AWS-хранилища.

Я пробовал установку ниже (это просто пробная версия и ошибка), но она не работает.

Application.rb

config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s] 
config.i18n.load_path += Dir["https://s3-eu-west-1.amazonaws.com/myapp/locales/", '*.{rb,yml}'.to_s] 
config.i18n.available_locales = [:en, :se] 

Edit: Мой текущий (утомительно) рабочий процесс, чтобы создать все переводы в базе данных (с использованием базы данных переводов является обязательным для Absolut меня кстати). Затем я экспортирую таблицу в yaml в мое хранилище AWS. Оттуда я загружаю файлы локали в свое локальное приложение и в папку locale. Я загружаю все это обратно Heroku снова. Все потому, что я не могу писать в файловую систему Heroku.

Как настроить мое приложение так, чтобы локальные файлы (например, https://s3-eu-west-1.amazonaws.com/myapp/locales/en.yml) считывались из этого внешнего источника? Возможно ли это? Если нет, есть ли обходной путь?

+0

Почему вы не развертываете файлы локали как часть приложения и не ссылаетесь на них из эфемерной файловой системы? –

+0

Кажется, мой ответ на вас исчез. В принципе, я уже делаю то, что вы предлагаете (как в моем текстовом редакторе), но я часто создаю новые элементы, которые нуждаются в новых переводах, и мне нужно сделать это в живой версии. Это означает, что мне нужно делать всю цепочку DB-> Yaml-> AWS-> local-> Heroku каждый раз. – Christoffer

ответ

1

Я чувствую, вы не можете добавлять внешние переводы напрямую, используя «Dir». Потому что он работает локально. Чтобы обходной путь, вы можете загрузить внешний файл в локальную систему, а затем использовать Dir для доступа к нему в I18n таким же образом. В любом случае, для загрузки любых изменений во внешний файл, вам всегда потребуется перезагрузить ваш производственный сервер. Таким образом, это то же самое, что хранить файл локально.

+0

Я действительно не понимаю, что вы имеете в виду, «загрузите внешний файл в локальную систему». Вы хотите скопировать его в мою локальную систему? В этом случае он разрушает всю суть его во внешней файловой системе, если мне нужно добавить это исправление вручную. – Christoffer

+0

Тогда вам может понадобиться настроить собственный метод перевода, который каждый раз вызывает внешний файл и извлекает ваши переводы оттуда. Но это не оптимизировано. Также во время загрузки приложения настраиваются также переводы Rails. Поэтому вам нужен файл для его загрузки. Я чувствую, что вы не можете сделать это, используя рельсы текущего I18n, не имея файла перевода в системе rails. –

+0

У меня все еще есть проблема с пониманием того, что вы пишете, даже после прочтения через пару раз. Но я понимаю, что вы говорите, что это действительно невозможно. Я хотел бы получить больше мнений об этом и, возможно, обходных решениях этой проблемы. – Christoffer

2

Что приходит на ум - это реализация кеша для вашей базы данных (поэтому вам не нужно использовать любые файлы YML). Во-первых, если ключ был достигнут, результат кэшируется и при втором поиске - i18n будет использовать кешированное значение.

I18n::Backend::ActiveRecord.send(:include, I18n::Backend::Cache) 
I18n.cache_store = ActiveSupport::Cache.lookup_store(:memory_store) # or whatever store you prefer 

Один из способов продолжения - разогреть кеш, используя: I18n.cache_store.write({"en.some.key" => "value"}). Я думаю, это не должно быть слишком сложно заполнить его из базы данных.

Проблема заключается в том, что вы хотите сделать недействительным кеш. Вам нужно будет создать собственный бэкэнд для activerecord. Here - магазин способ. Вам нужно будет создать новый бэкэнд-модуль, который очистит и перезапишет кеш.

def store_translations(locale, data, options = {}) 
    I18n.cache_store.clear 
    super 
    I18n.cache_store.write(#cached_values) 
end 

Если кэш очень большой вам нужно реализовать умнее store_translation метод, который управляет конкретным пунктом перевода.

Это немного armchair-engineering, но с некоторым усилием я думаю, что вы сможете создать надежный накопитель для ваших переводов activerecord.

+0

Спасибо за помощь. Это может быть полезным решением, хотя это был не тот, на который я надеялся :) Похоже, я не могу решить его так, как задает мой вопрос, но я оставлю вопрос открытым на некоторое время. – Christoffer