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

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


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


Ответы (2)


Вместо того, чтобы фактически передавать детали конфигурации тому клиенту 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

Есть смысл?

person coreyward    schedule 01.10.2011
comment
Большое спасибо. Я дам ему попробовать. - person Sait Mesutcan Ilhaner; 03.10.2011
comment
Отлично работает, большое спасибо. Просто быстрый вопрос: допустим, у меня есть метод класса, и я хочу использовать для них ассоциации. Как это сделать? - person Sait Mesutcan Ilhaner; 04.10.2011
comment
извините, я просто что-то набрал, но не хотел задавать вопрос, но затем дважды нажал Enter, и он опубликовал это. - person Sait Mesutcan Ilhaner; 04.10.2011
comment
Большой. Если это сработало для вас, продолжайте и примите это как ответ, щелкнув контур флажка слева от вопроса. :) - person coreyward; 04.10.2011

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

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

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, что означает, что все инициализаторы и все остальное уже будут выполнены, поэтому это может быть слишком далеко по цепочке.

person d11wtq    schedule 03.10.2011
comment
Большое спасибо. Это было действительно полезно. Раньше я никогда ничего не делал со стеком промежуточного ПО, за исключением случаев, когда использовал OmniAuth и Devise. Я никогда раньше не писал свое промежуточное ПО. - person Sait Mesutcan Ilhaner; 04.10.2011
comment
Я думаю, что большинство людей не понимают, что промежуточное ПО — это всего лишь один метод :) - person d11wtq; 05.10.2011