Il modo migliore per creare opzioni di configurazione personalizzate per la mia app Rails?


133

Devo creare un'opzione di configurazione per la mia applicazione Rails. Può essere lo stesso per tutti gli ambienti. Ho scoperto che se l'ho impostato environment.rb, è disponibile nelle mie viste, che è esattamente quello che voglio ...

environment.rb

AUDIOCAST_URI_FORMAT = http://blablalba/blabbitybla/yadda

Funziona alla grande.

Tuttavia, sono un po 'a disagio. È un buon modo per farlo? C'è un modo che è più alla moda?

Risposte:


191

Per la configurazione generale dell'applicazione che non necessita di essere archiviata in una tabella di database, mi piace creare un config.ymlfile nella directory di configurazione . Per il tuo esempio, potrebbe apparire così:

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

development:
  <<: *defaults

test:
  <<: *defaults

production:
  <<: *defaults

Questo file di configurazione viene caricato da un inizializzatore personalizzato in config / initializer :

# 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]

Se stai usando Rails 3, assicurati di non aggiungere accidentalmente una barra iniziale al percorso di configurazione relativo.

È quindi possibile recuperare il valore utilizzando:

uri_format = APP_CONFIG['audiocast_uri_format']

Vedi questo Railscast per tutti i dettagli.


1
Potrebbe essere necessario YAML::ENGINE.yamler = 'syck'per far funzionare tutto stackoverflow.com/a/6140900/414220
evanrmurphy

45
Solo un FYI, in Rails 3.x devi sostituirlo RAILS_ENVcon Rails.enve RAILS_ROOTcon Rails.root.
JeanMertz,

5
Per Rails 3+ devi unirti al percorso relativo, non assoluto. Non aggiungere il prefisso alla directory di configurazione con barra.
wst

10
Non sei sicuro delle versioni precedenti, ma in Rails 4.1 puoi farloRails.application.config.whatever_you_want = YAML.load_file(Rails.root.join('config', 'config.yml'))[Rails.env]
d4rky il

2
@ iphone007 è infatti possibile caricare file yaml arbitrari dalla directory di configurazione. vedi la risposta di Smathy al di sotto della quale, a mio avviso, dovrebbe essere la risposta accettata.
omnikron,

82

La versione di Rails 3 del codice dell'inizializzatore è la seguente (RAILS_ROOT e RAILS_ENV sono obsoleti)

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

Inoltre, Ruby 1.9.3 usa Psych che rende le chiavi di unione sensibili al maiuscolo / minuscolo, quindi dovrai cambiare il tuo file di configurazione per tenerne conto, ad es.

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

development:
  <<: *DEFAULTS

test:
  <<: *DEFAULTS

production:
  <<: *DEFAULTS

3
Non hai bisogno "#{Rails.root.to_s}"; "#{Rails.root}"lavori.
David J.

3
Consiglio Rails.root.join('config', 'config.yml')invece di"#{Rails.root.to_s}/config/config.yml"
David J.

2
E, invece di APP_CONFIG, ti consiglio di usare:AppName::Application.config.custom
David J.

1
David, i tuoi primi due commenti sono le migliori pratiche e aggiungerò il codice, ma l'ultimo lo tralascerò perché ciò significa che devi ricordare di cambiare l'AppName ogni volta che usi questo codice.
David Burrows,

53

Rotaie> = 4.2

Basta creare un YAMLfile in config/directory, ad esempio: config/neo4j.yml.

Il contenuto di neo4j.ymlpuò essere simile al seguente (per semplicità, ho usato il valore predefinito per tutti gli ambienti):

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

development:
  <<: *default

test:
  <<: *default

production:
  <<: *default

in config/application.rb:

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

Ora, la tua configurazione personalizzata è accessibile come di seguito:

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

Ulteriori informazioni

Il documento API ufficiale di Rails descrive il config_formetodo come:

Convenienza per il caricamento di config / foo.yml per l'attuale ambiente Rails.


Se non si desidera utilizzare un yamlfile

Come dice la guida ufficiale di Rails:

È possibile configurare il proprio codice tramite l'oggetto di configurazione Rails con la configurazione personalizzata nella config.xproprietà.

Esempio

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

Questi punti di configurazione sono quindi disponibili tramite l'oggetto di configurazione:

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

Riferimento ufficiale per il config_formetodo | Guida ufficiale delle rotaie


25

Passaggio 1: creare config / initializer / 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)

Passaggio 2: creare config / config.yml

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

development:
  <<: *common

test:
  <<: *common

production:
  <<: *common

Passaggio 3: ottenere le costanti ovunque nel codice

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

Come leggiamo la variabile ENV in config.yml, la mia configurazione è la stessa .. ho aggiunto la variabile in bashrc e sto cercando di leggerla in config.yml usando la chiave: <% = ENV [URL]%> ... questo non funziona
Shiva,

@shiva Guarda nella gemma di Figaro per le variabili ENV. Questa configurazione di configurazione è per i valori che non devono essere nascosti dal controllo del codice sorgente.
Shadoath

17

Volevo solo aggiornare questo per le ultime cose interessanti in Rails 4.2 e 5, ora puoi farlo all'interno di uno qualsiasi dei tuoi config/**/*.rbfile:

config.x.whatever = 42

(e questo è letterale xlì dentro, cioè il config.x.letterale deve essere quello, e quindi puoi aggiungere quello che vuoi dopo il x)

... e questo sarà disponibile nella tua app come:

Rails.configuration.x.whatever

Vedi di più qui: http://guides.rubyonrails.org/configuring.html#custom-configuration


3
Solo un chiarimento che inizialmente ha causato un problema per me; la x non è un segnaposto per qualunque cosa tu voglia inserire, deve davvero essere la lettera x.
Tobinibot,

Ottimo punto @tobinibot: ho aggiunto questo chiarimento alla mia risposta, grazie.
Smathy

È interessante notare che le guide in realtà non menzionano la 'x', ma posso attestare che è ancora necessario a partire da Rails 5.0
Don

Hai ragione Don, è strano - sono sicuro che lo diceva.
Smathy

1
Dai documenti di rotaia attuali: 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).Fonte: guide.rubyonrails.org/configuring.html#custom-configuration
David Gay

6

Solo alcune informazioni extra su questo argomento:

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

".with_indifferent_access" ti consente di accedere ai valori nell'hash usando una chiave stringa o con una chiave simbolo equivalente.

per esempio.
APP_CONFIG['audiocast_uri_format'] => 'http://blablalba/blabbitybla/yadda' APP_CONFIG[:audiocast_uri_format] => 'http://blablalba/blabbitybla/yadda'

Praticamente una cosa comoda, ma preferisco che le mie chiavi siano rappresentate come simboli.


5

Uso qualcosa di simile a John per Rails 3.0 / 3.1, ma prima ho il codice di analisi del file:

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

Questo mi permette di usare ERB nella mia configurazione se necessario, come leggere l'URL redistogo di heroku:

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

2
Non penso che ne avrei bisogno ogni giorno, ma questa è una soluzione davvero interessante per quei momenti in cui ne hai bisogno. Penso che cambierei il nome del file in config.yml.erb per abbinare la convenzione delle rotaie.
Andrew Burns,

2

Rails 4

Per creare una configurazione personalizzata yaml e caricarla (e renderla disponibile per la tua app) simile a come database_configuration.

Crea il tuo *.yml, nel mio caso avevo bisogno di un file di configurazione redis.

config/redis.yml

default: &default
  host: localhost
  port: 6379

development:
  <<: *default

test:
  <<: *default

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

Quindi caricare la configurazione

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

Accedi ai valori:

Rails.configuration.redis_configuration[Rails.env]simile a come si può avere accesso al vostro database.ymlperRails.configuration.database_configuration[Rails.env]


Si potrebbe anche risparmiare un po 'di tempo prendendo solo le impostazioni per l'ambiente corrente, che sono presumibilmente gli unici in ogni caso è necessario: Rails.configuration.redis_configuration = YAML.load_file("#{Rails.root}/config/redis.yml")[Rails.env]. Tuttavia, nelle rotaie 4.2 e successive la risposta di Smathy è probabilmente un modo più semplice di procedere.
omnikron,

1

Basandomi sull'elegante soluzione di Omer Aslam, ho deciso di convertire le chiavi in ​​simboli. L'unica modifica è:

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

Ciò consente di fare riferimento ai valori mediante simboli come chiavi, ad es

AppConfig[:twitter][:key]

Questo mi sembra più pulito.

(Inserito come risposta in quanto la mia reputazione non è abbastanza elevata da commentare la risposta di Omer)




0

Preferisco accedere alle impostazioni tramite lo stack di applicazioni globali. Evito le variabili globali in eccesso nell'ambito locale.

config / inizializzatori / myconfig.rb

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

E accedervi con.

MyAppName::Application.myconfig["yamlstuff"]

0

Il mio modo di caricare le impostazioni prima dell'inizializzazione di Rails

Consente di utilizzare le impostazioni nell'inizializzazione di Rails e configurare le impostazioni per ambiente

# 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)}

È possibile ottenere le impostazioni in due modi: Impostazioni ['email'] o Settings.email


0

Il mio modo migliore per la configurazione personalizzata, con messaggio sollevato quando manca setting.yml.

viene caricato da un inizializzatore personalizzato in config / initializer / 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]

Crea uno YAML in config / setting.yml

development:
  app_id: 433387212345678
  app_secret: f43df96fc4f65904083b679412345678

test:
  app_id: 148166412121212
  app_secret: 7409bda8139554d11173a32222121212

production:
  app_id: 148166412121212
  app_secret: 7409bda8139554d11173a32222121212
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.