Найкращий спосіб створити спеціальні параметри конфігурації для мого додатка Rails?


133

Мені потрібно створити один варіант конфігурації для моєї програми Rails. Це може бути однаково для всіх середовищ. Я виявив, що якщо я встановив його environment.rb, він доступний в моїх поглядах, і саме це я хочу ...

environment.rb

AUDIOCAST_URI_FORMAT = http://blablalba/blabbitybla/yadda

Чудово працює.

Однак мені трохи неприємно. Це хороший спосіб зробити це? Чи є спосіб, що більше стегна?

Відповіді:


191

Для загальної конфігурації програми, яку не потрібно зберігати в таблиці бази даних, я хотів би створити config.ymlфайл у каталозі config . Для вашого прикладу це може виглядати приблизно так:

defaults: &defaults
  audiocast_uri_format: http://blablalba/blabbitybla/yadda

development:
  <<: *defaults

test:
  <<: *defaults

production:
  <<: *defaults

Цей файл конфігурації завантажується з користувацького ініціалізатора в config / inicijalizer :

# Rails 2
APP_CONFIG = YAML.load_file("#{RAILS_ROOT}/config/config.yml")[RAILS_ENV]

# Rails 3+
APP_CONFIG = YAML.load_file(Rails.root.join('config/config.yml'))[Rails.env]

Якщо ви використовуєте Rails 3, переконайтеся, що ви випадково не додали провідну косу рису до відносного конфігураційного шляху.

Потім ви можете отримати значення, використовуючи:

uri_format = APP_CONFIG['audiocast_uri_format']

Дивіться цю Railscast для повної інформації.


1
Вам може знадобитися YAML::ENGINE.yamler = 'syck'для цього роботи stackoverflow.com/a/6140900/414220
evanrmurphy

45
Просто FYI, в Rails 3.x вам потрібно замінити RAILS_ENVз Rails.envі RAILS_ROOTз Rails.root.
ЖанМерц

5
Для Rails 3+ ви повинні приєднатися до відносного шляху, а не до абсолютного. Не префіксуйте конфігураційний каталог з косою рисою.
wst

10
Не впевнений у попередніх версіях, але в Rails 4.1 ви можете це зробитиRails.application.config.whatever_you_want = YAML.load_file(Rails.root.join('config', 'config.yml'))[Rails.env]
d4rky

2
@ iphone007 дійсно можна завантажити довільні файли yaml з каталогу config. дивіться відповідь сміття нижче, на яку, на мою думку, зараз слід прийняти відповідь.
omnikron

82

Версія коду ініціалізатора Rails 3 є такою (RAILS_ROOT & RAILS_ENV застаріли)

APP_CONFIG = YAML.load_file(Rails.root.join('config', 'config.yml'))[Rails.env]

Крім того, Ruby 1.9.3 використовує Psych, який робить ключі злиття чутливими до регістру, тому вам потрібно буде змінити конфігураційний файл, щоб врахувати це, наприклад

defaults: &DEFAULTS
  audiocast_uri_format: http://blablalba/blabbitybla/yadda

development:
  <<: *DEFAULTS

test:
  <<: *DEFAULTS

production:
  <<: *DEFAULTS

3
Вам не потрібно "#{Rails.root.to_s}"; "#{Rails.root}"працює.
Девід Дж.

3
Рекомендую Rails.root.join('config', 'config.yml')замість"#{Rails.root.to_s}/config/config.yml"
David J.

2
І замість APP_CONFIG рекомендую використовувати:AppName::Application.config.custom
Девід Дж.

1
Девіде, ваші перші два коментарі - найкраща практика, і я поправлю код, але останній я збираюся залишити, оскільки це означає, що вам потрібно пам’ятати, щоб змінювати AppName кожен раз, коли ви використовуєте цей код.
Девід Берроуз

53

Рейки> = 4,2

Просто створіть YAMLфайл в config/каталозі, наприклад: config/neo4j.yml.

Вміст neo4j.ymlможе бути таким, як нижче (Для простоти, я використовував за замовчуванням для всіх середовищ):

default: &default
  host: localhost
  port: 7474
  username: neo4j
  password: root

development:
  <<: *default

test:
  <<: *default

production:
  <<: *default

в config/application.rb:

module MyApp
  class Application < Rails::Application
    config.neo4j = config_for(:neo4j)
  end
end

Тепер ваш користувальницький конфігур доступний, як показано нижче:

Rails.configuration.neo4j['host'] #=>localhost
Rails.configuration.neo4j['port'] #=>7474

Більше інформації

Офіційний документ API Rails описує config_forметод як:

Зручність для завантаження config / foo.yml для поточного оточення Rails.


Якщо ви не хочете використовувати yamlфайл

Як говорить офіційний посібник Rails:

Ви можете налаштувати власний код через об’єкт конфігурації Rails із власною конфігурацією під config.xвластивістю.

Приклад

config.x.payment_processing.schedule = :daily
config.x.payment_processing.retries  = 3
config.x.super_debugger = true

Ці точки конфігурації потім доступні через об’єкт конфігурації:

Rails.configuration.x.payment_processing.schedule # => :daily
Rails.configuration.x.payment_processing.retries  # => 3
Rails.configuration.x.super_debugger              # => true
Rails.configuration.x.super_debugger.not_set      # => nil

Офіційна довідка щодо config_forметоду | Офіційне керівництво по рейках


25

Крок 1: Створіть конфігурацію / ініціалізатори / appconfig.rb

require 'ostruct'
require 'yaml'

all_config = YAML.load_file("#{Rails.root}/config/config.yml") || {}
env_config = all_config[Rails.env] || {}
AppConfig = OpenStruct.new(env_config)

Крок 2: Створіть config / config.yml

common: &common
  facebook:
    key: 'asdjhasxas'
    secret : 'xyz'
  twitter:
    key: 'asdjhasxas'
    secret : 'abx'

development:
  <<: *common

test:
  <<: *common

production:
  <<: *common

Крок 3. Отримайте константи в будь-якому місці коду

facebook_key = AppConfig.facebook['key']
twitter_key  = AppConfig.twitter['key']

Як ми читаємо змінну ENV в config.yml, моя конфігурація така ж. Я додав змінну в bashrc, і я намагаюся прочитати її в config.yml за допомогою ключа: <% = ENV [URL]%> ... це не працює
shiva

@shiva Подивіться у дорогоцінний камінь Figaro для ENV-змінних. Ця настройка конфігурації призначена для значень, які не потрібно приховувати від керування джерелом.
Shadoath

17

Я просто хотів оновити це для останніх цікавих матеріалів в Rails 4.2 і 5, тепер ви можете це зробити всередині своїх config/**/*.rbфайлів:

config.x.whatever = 42

(і це буквально xтам, тобто config.x.буквально повинно бути таким, і після цього ви можете додавати все, що завгодно x)

... і це буде доступне у вашій програмі як:

Rails.configuration.x.whatever

Детальніше тут: http://guides.rubyonrails.org/configuring.html#custom-configuration


3
Просто уточнення, яке спочатку спричинило проблему для мене; x не є заповнювачем для того, що ви хочете вкласти, це справді має бути буквою x.
tobinibot

Чудовий момент @tobinibot - я додав це пояснення до своєї відповіді, дякую.
сміття

Цікаво, що в путівниках насправді не згадується "х", але я можу засвідчити, що це все-таки необхідно з Rails 5.0
Don

Ти маєш рацію Дон, це дивно - я впевнений, що раніше це говорив.
сміття

1
Із поточних документів рейки: You can configure your own code through the Rails configuration object with custom configuration under either the config.x namespace, or config directly. The key difference between these two is that you should be using config.x if you are defining nested configuration (ex: config.x.nested.nested.hi), and just config for single level configuration (ex: config.hello).Джерело: guides.rubyonrails.org/configuring.html#custom-configuration
Девід Гей

6

Лише додаткова інформація на цю тему:

APP_CONFIG = YAML.load_file(Rails.root.join('config', 'config.yml'))[Rails.env].with_indifferent_access

".with_indifferent_access" дозволяє отримати доступ до значень у хеші за допомогою рядкового ключа або з еквівалентним символьним ключем.

напр.
APP_CONFIG['audiocast_uri_format'] => 'http://blablalba/blabbitybla/yadda' APP_CONFIG[:audiocast_uri_format] => 'http://blablalba/blabbitybla/yadda'

Цілком зручна річ, але я вважаю за краще, щоб мої ключі були представлені як символи.


5

Я використовую щось подібне до John для Rails 3.0 / 3.1, але я спочатку проаналізував файл erb:

APP_CONFIG = YAML.load(ERB.new(File.new(File.expand_path('../config.yml', __FILE__)).read).result)[Rails.env]

Це дозволяє мені використовувати ERB в моїй конфігурації, якщо мені потрібно, як, наприклад, читати redistogo URL-адресу heroku:

production:
  <<: *default
  redis:                  <%= ENV['REDISTOGO_URL'] %>

2
Я не думаю, що мені це буде потрібно щодня, але це справді класне рішення для тих часів, коли це потрібно. Думаю, я б змінив ім'я файлу на config.yml.erb, хоча і відповідати умовам рейки.
Ендрю Бернс

2

Rails 4

Щоб створити користувальницьку конфігурацію yaml та завантажити її (та зробити її доступною для вашої програми), аналогічно як database_configuration .

Створіть свій *.yml, у моєму випадку мені знадобився файл конфігурації redis.

config/redis.yml

default: &default
  host: localhost
  port: 6379

development:
  <<: *default

test:
  <<: *default

production:
  <<: *default
  host: <%= ENV['ELASTICACHE_HOST'] %>
  port: <%= ENV['ELASTICACHE_PORT'] %>

Потім завантажте конфігурацію

config/application.rb

module MyApp
  class Application < Rails::Application

    ## http://guides.rubyonrails.org/configuring.html#initialization-events
    config.before_initialize do
      Rails.configuration.redis_configuration = YAML.load_file("#{Rails.root}/config/redis.yml")
    end

  end
end

Доступ до значень:

Rails.configuration.redis_configuration[Rails.env]аналогічно тому, як ви можете мати доступ до свого database.ymlкористувачаRails.configuration.database_configuration[Rails.env]


Ви також можете заощадити деякий час, тільки беручи настройки для поточного середовища, які, ймовірно, тільки ті , що вам потрібно в будь-якому випадку: Rails.configuration.redis_configuration = YAML.load_file("#{Rails.root}/config/redis.yml")[Rails.env]. Однак у рельсах 4.2 і вище відповідь на розсуд, мабуть, є більш простим способом.
omnikron

1

Спираючись на елегантне рішення Омера Аслама, я вирішив перетворити ключі в символи. Єдина зміна:

all_config = YAML.load_file("#{Rails.root}/config/config.yml").with_indifferent_access || {}

Це дозволяє потім посилати значення за символами як ключі, наприклад

AppConfig[:twitter][:key]

Це здається охайнішим для моїх очей.

(Опубліковано як відповідь, оскільки моя репутація недостатньо висока, щоб коментувати відповідь Омера)



0

дивіться мою відповідь на те, де найкраще місце для зберігання параметрів програми: база даних, файл, код ...?

Варіант того, що у вас було в тому, що це проста посилання на інший файл. Він бачить, що Environment.rb не постійно оновлюється і не містить у собі куточки конкретних додатків. Хоча це не конкретна відповідь на ваше запитання "чи це шлях рейків?", Можливо, там буде якась дискусія.


0

Я віддаю перевагу доступу до налаштувань через глобальний стек додатків. Я уникаю надмірних глобальних змінних в локальному масштабі.

config / ініціалізатори / myconfig.rb

MyAppName::Application.define_singleton_method("myconfig") {YAML.load_file("#{Rails.root}/config/myconfig.yml") || {}}

І отримати доступ до нього за допомогою.

MyAppName::Application.myconfig["yamlstuff"]

0

Мій спосіб завантажити налаштування до ініціалізації Rails

Дозволяє використовувати налаштування в ініціалізації Rails та конфігурувати параметри для середовища

# config/application.rb
Bundler.require(*Rails.groups)

mode = ENV['RAILS_ENV'] || 'development'
file = File.dirname(__FILE__).concat('/settings.yml')
Settings = YAML.load_file(file).fetch(mode)
Settings.define_singleton_method(:method_missing) {|name| self.fetch(name.to_s, nil)}

Ви можете отримати налаштування двома способами: Налаштування ['email'] або Settings.email


0

Мій найкращий спосіб налаштувати конфігурацію, з повідомленням підвищення під час налаштування.yml відсутній.

завантажується з користувацького ініціалізатора в config / inicijalizer / custom_config.rb

setting_config = File.join(Rails.root,'config','setting.yml')
raise "#{setting_config} is missing!" unless File.exists? setting_config
config = YAML.load_file(setting_config)[Rails.env].symbolize_keys

@APP_ID = config[:app_id]
@APP_SECRET = config[:app_secret]

Створіть YAML у config / settings.yml

development:
  app_id: 433387212345678
  app_secret: f43df96fc4f65904083b679412345678

test:
  app_id: 148166412121212
  app_secret: 7409bda8139554d11173a32222121212

production:
  app_id: 148166412121212
  app_secret: 7409bda8139554d11173a32222121212
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.