Доступ к 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
Итак, что происходит?
Ответы
Ответ 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.