Доступ к конфигурации из application.rb в контроллере (Rails 3) - PullRequest
24 голосов
/ 10 ноября 2010

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

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

Ответы [ 5 ]

45 голосов
/ 10 ноября 2010

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

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

Сначала создайте модуль Twiter Config:

#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]
13 голосов
/ 14 октября 2011

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

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

Rails.application.config.time_zone

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

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

config.twitter_key = 'foo'

А потом читайте это где-нибудь в вашем коде:

Rails.application.config.twitter_key

5 голосов
/ 10 ноября 2010

Возможно, вы захотите использовать подход с использованием файла 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']
0 голосов
/ 14 июня 2011

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

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

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

0 голосов
/ 10 ноября 2010

Просто поместите файл в 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-файлов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...