Подтвердить что ты не робот

Доступ к config из приложения .rb в контроллере (Rails 3)

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

# Extra
config.twitter.key = 'foo'
config.twitter.secret = 'bar'

Я пытаюсь получить к ним доступ, используя три предложенных метода:

self.config.twitter.key # Should be extended through ApplicationController Base
config.twitter.key # Inherited but with different syntax
CONFIG['twitter']['key'] #some massive magical array that apparently exists somewhere

Все они дают мне разные виды ошибок, когда я передаю их через метод "отладки", например:

debug self.config.twitter.key # undefined method `key' for nil:NilClass

Итак, что происходит?

4b9b3361

Ответ 1

Я считаю, что у вас есть некорректная идея, стоящая за вашими ожиданиями для config/application.rb. ActiveRecord:: Base и ActiveController:: Base eigenclasses используют класс Rails:: Application:: Configuration, который настроен в config/application.rb. Атрибуты недоступны в классах, которые спускаются с любого из базовых классов, а также на их собственные. Вот почему вы сталкиваетесь с ошибками в ApplicationController.

Как правило, есть два способа сделать инициализацию конфигурации в приложении Rails. Первый способ - создать модуль конфигурации, а затем загрузить в него значения через инициализатор:

Сначала создайте модуль конфигурации Twiter:

#lib/twitter_config.rb
module TwitterConfig
  def self.config
    @@config ||= {}
  end

  def self.config=(hash)
    @@config = hash
  end
end

Создайте конфигурационный файл YAML:

# config/twitter.yaml
development: &base
  key: "foo"
  secret: "bar"

test:
 <<: *base
 key: "foo2"

production:
  <<: *base
  secret: "barbar"

В качестве альтернативы, если вы не собираетесь добавлять config/twitter.yaml в свой SCM, вы можете просто пропустить это и установить ключ и секрет через переменные среды. Это будет предлагаемое решение для приложения с открытым хранилищем SCM, развертывающимся на Heroku.

Затем загрузите и установите значение через инициализатор:

#config/initializers/01_twitter.rb
require 'twitter_config'

TwitterConfig.config = YAML.load_file("config/config.yml")[Rails.env].symbolize_keys

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

#config/initializers/01_twitter.rb
require 'twitter_config'

TwitterConfig.config[:key] = ENV['twitter_config_key']
TwitterConfig.config[:secret] = ENV['twitter_config_secret']

В приложении Rails теперь у вас есть доступ к значениям конфигурации с помощью TwitterConfig.config [: key] и TwitterConfig.config [: secret]. Вы также можете включить модуль, просто следите за конфликтами.

Вы также можете просто загрузить значения в качестве глобальной константы. Мне это кажется немного уродливым:

#config/application.rb
TWITTER_CONFIG = YAML.load_file("config/twitter.yaml")[Rails.env]

Ответ 2

Я пробовал это и, кажется, работаю, вы можете использовать:: Rails.application.config.

Например, я использую его для получения правильного набора времени в приложении следующим образом:

Rails.application.config.time_zone

Я нашел это благодаря коду с меньшей рельсами: https://github.com/metaskills/less-rails/blob/master/lib/less/rails/helpers.rb

Таким образом, вы можете объявить это в своем приложении .rb или в любом файле среды:

config.twitter_key = 'foo'

И затем прочитайте его так, как угодно в вашем коде:

Rails.application.config.twitter_key

Ответ 3

Возможно, вам захочется использовать подход к файлу yaml.

В application.rb

CONFIG = YAML.load_file("config/config.yml")[Rails.env]

В config/config.yml

development: &base_config
    twitter_key = "foo"
    twitter_secret = "bar"

test:
  <<: *base_config
    twitter_key = "foo2"

production:
  <<: *base_config
    twitter_secret = "barbar"

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

CONFIG['twitter_key']

Ответ 4

Небольшое обновление общепринятого ответа здесь: Доступ к config из приложения .rb в контроллере (Rails 3)

Методы внутри модуля TwitterConfig должны быть методами класса (или модульными методами, если вы так предпочитаете). Они не могут быть методами экземпляра.

Извините, что поставил это в ответ, но я не смог найти способ прокомментировать этот ответ.

Ответ 5

Просто поместите файл в config/initializers/ как app_config.rb Если вы используете константу ENV, вы можете в дальнейшем легко развернуть ее в Heroku, установив значения с помощью команды heroku config:add twitter_key=mypublickey.

Что-то вроде этого:

## config/initializers/app_config.rb
unless Rails.env.production?
  ENV['twitter_key']    = 'foo'
  ENV['twitter_secret'] = 'bar'
end

Вы сохраняете свои производственные ключи вне контроля версий и не должны вводить файлы YAML.