Bezdepbonusu7Программирование: статьи и ответы

Вопрос

Передача переменных в config/environments/demo.rb из приложения Rails

Автор вопроса: Sait Mesutcan IlhanerОтветов: 2

В последние дни я боролся с проблемой в приложении Ruby on Rails, над которым я сейчас работаю. У меня разные страны, и для каждой страны мы используем разные корзины Amazon S3. Учетные данные ключа Amazon S3 хранятся как константы в config/environments/environment_name.rb(ex:demo.rb). Я не могу определить, в какой стране мы работаем, из файла конфигурации. Я могу определить, в какой стране мы работаем, по контроллерам, моделям, представлениям и т. д., но не по файлу конфигурации. Есть ли метапрограммирование Ruby или какая-то другая магия, о которой я не знаю, поэтому я хочу сказать, работаем ли мы над Великобританией как страной в приложении, используем учетные данные корзины Великобритании или Германию как страну, используем немецкую учетные данные корзины? Я не могу придумать способ передать параметры в файлы среды из самого приложения. Заранее большое спасибо за всю вашу помощь.

  • У вас есть пример того, как вы это делаете в контроллерах? Это связано с GeoIP или вы устанавливаете какой-то флаг вручную? d11wtq 01.10.2011
  • Причина, по которой я спрашиваю, заключается в том, что я думаю, что вы ищете промежуточное программное обеспечение, которое устанавливает некоторую дополнительную конфигурацию на основе запроса непосредственно перед выполнением рельсов. d11wtq 01.10.2011
  • Это не вопрос геоипа, я устанавливаю все как константы в файлах среды и использую эти учетные данные в контроллерах. Sait Mesutcan Ilhaner 03.10.2011
  • Так это основано на окружающей среде? d11wtq 03.10.2011
  • Да, это зависит от окружающей среды. У нас есть разные ведра для каждой среды. Sait Mesutcan Ilhaner 03.10.2011
  • Ответ добавлен с примером промежуточного программного обеспечения. d11wtq 04.10.2011

rubyruby-on-railsmodel-view-controllerruntimemetaprogramming

Ответы

Ответ 1 · coreyward

Вместо того, чтобы фактически передавать детали конфигурации тому клиенту S3, который вы используете при запуске, вам, вероятно, следует выбирать соответствующие учетные данные для каждого запроса. Ваш конфигурационный файл может определить их все в хеше следующим образом:

# config/s3.rb
S3_BUCKETS => {
  :us => 'our-files-us',
  :gb => 'our-files-gb',
  :tz => 'special-case'
}

Затем вы можете выбрать учетные данные по запросу (возможно, в вашем AppController):

bucket_name = S3_BUCKETS[I18n.locale]
# pass this info to your S3 client

Есть смысл?

Ответ 2 · d11wtq

Напишите небольшое промежуточное программное обеспечение, если вы хотите сохранить информацию о конфигурации для каждой страны вне основного приложения.

Промежуточное ПО очень простое. Ничего не делающее промежуточное ПО выглядит так:

class DoesNothing
  def initialize(app, *args)
    @app = app
  end

  def call(env)
    @app.call(env)
  end
end

Стойка поддерживает приложения за счет объединения в цепочку ряда промежуточных программ... каждому из них дается ссылка на @app, который является следующим звеном в цепочке, и он должен вызывать #call для этого приложения. Тот, что в конце цепочки, запускает приложение.

Итак, в вашем случае вы можете выполнить дополнительную настройку здесь.

class PerCountryConfiguration
  def initialize(app)
    @app = app
  end

  def call(env)
    case env["COUNTRY"]
      when "AU"
        Rails.application.config.s3_buckets = { ... }
      when "US"
        Rails.application.config.s3_buckets = { ... }
      ... etc
    end

    @app.call(env)
  end
end

Есть несколько способов использования промежуточного программного обеспечения, но, поскольку это зависит от доступа к среде Rails, вы захотите сделать это изнутри Rails. Поместите это в свой application.rb:

config.middleware.use PerCountryConfiguration

Если вы хотите передать дополнительные аргументы конструктору промежуточного программного обеспечения, просто перечислите их после имени класса:

config.middleware.use PerCountryConfiguration, :some_argument

Вы также можете смонтировать промежуточное программное обеспечение изнутри ApplicationController, что означает, что все инициализаторы и все остальное уже будут выполнены, поэтому это может быть слишком далеко по цепочке.

Перевод вопроса и ответов сообщества Stack Overflow, лицензия CC BY-SA. Оригинал на Stack Overflow.

Похожие материалы