Le meilleur moyen de créer des options de configuration personnalisées pour mon application Rails?


133

Je dois créer une option de configuration pour mon application Rails. Cela peut être le même pour tous les environnements. J'ai trouvé que si je l'installe environment.rb, il est disponible dans mes vues, ce qui est exactement ce que je veux ...

environment.rb

AUDIOCAST_URI_FORMAT = http://blablalba/blabbitybla/yadda

Fonctionne très bien.

Cependant, je suis un peu inquiet. Est-ce une bonne façon de procéder? Y a-t-il un moyen plus branché?

Réponses:


191

Pour la configuration d'application générale qui n'a pas besoin d'être stockée dans une table de base de données, j'aime créer un config.ymlfichier dans le répertoire de configuration . Pour votre exemple, cela pourrait ressembler à ceci:

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

development:
  <<: *defaults

test:
  <<: *defaults

production:
  <<: *defaults

Ce fichier de configuration est chargé à partir d'un initialiseur personnalisé dans config / initializers :

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

Si vous utilisez Rails 3, assurez-vous de ne pas ajouter accidentellement une barre oblique à votre chemin de configuration relatif.

Vous pouvez ensuite récupérer la valeur en utilisant:

uri_format = APP_CONFIG['audiocast_uri_format']

Voir ce Railscast pour plus de détails.


1
Vous devrez peut-être YAML::ENGINE.yamler = 'syck'pour que cela fonctionne stackoverflow.com/a/6140900/414220
evanrmurphy

45
Juste un FYI, dans Rails 3.x, vous devez remplacer RAILS_ENVpar Rails.envet RAILS_ROOTpar Rails.root.
JeanMertz

5
Pour Rails 3+, vous devez joindre un chemin relatif, pas absolu. Ne préfixez pas le répertoire de configuration avec une barre oblique.
wst

10
Je ne suis pas sûr des versions précédentes, mais dans Rails 4.1, vous pouvez le faireRails.application.config.whatever_you_want = YAML.load_file(Rails.root.join('config', 'config.yml'))[Rails.env]
d4rky

2
@ iphone007 il est en effet possible de charger des fichiers yaml arbitraires depuis le répertoire config. voir la réponse de smathy ci-dessous qui, à mon avis, devrait maintenant être la réponse acceptée.
omnikron

82

La version Rails 3 du code d'initialisation est la suivante (RAILS_ROOT et RAILS_ENV sont obsolètes)

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

De plus, Ruby 1.9.3 utilise Psych qui rend les clés de fusion sensibles à la casse, vous devrez donc changer votre fichier de configuration pour en tenir compte, par exemple

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

development:
  <<: *DEFAULTS

test:
  <<: *DEFAULTS

production:
  <<: *DEFAULTS

3
Vous n'avez pas besoin "#{Rails.root.to_s}"; "#{Rails.root}"travaux.
David J.

3
Je recommande à la Rails.root.join('config', 'config.yml')place de"#{Rails.root.to_s}/config/config.yml"
David J.

2
Et, au lieu de APP_CONFIG, je recommande d'utiliser:AppName::Application.config.custom
David J.

1
David, vos deux premiers commentaires sont les meilleures pratiques et je vais modifier le code, mais le dernier que je vais laisser de côté car cela signifie que vous devez vous rappeler de changer le AppName chaque fois que vous utilisez ce code.
David Burrows

53

Rails> = 4,2

Créez simplement un YAMLfichier dans le config/répertoire, par exemple:config/neo4j.yml .

Le contenu de neo4j.ymlpeut être quelque chose comme ci-dessous (pour plus de simplicité, j'ai utilisé par défaut pour tous les environnements):

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

development:
  <<: *default

test:
  <<: *default

production:
  <<: *default

dans config/application.rb:

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

Maintenant, votre configuration personnalisée est accessible comme ci-dessous:

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

Plus d'informations

Le document officiel de l'API Rails décrit la config_forméthode comme suit:

Commodité pour charger config / foo.yml pour l'environnement Rails actuel.


Si vous ne souhaitez pas utiliser de yamlfichier

Comme le dit le guide officiel de Rails:

Vous pouvez configurer votre propre code via l'objet de configuration Rails avec une configuration personnalisée sous la config.xpropriété.

Exemple

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

Ces points de configuration sont ensuite disponibles via l'objet de configuration:

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

Référence officielle de la config_forméthode | Guide officiel des rails


25

Étape 1: Créez config / initializers / 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)

Étape 2: Créez config / config.yml

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

development:
  <<: *common

test:
  <<: *common

production:
  <<: *common

Étape 3: Obtenez des constantes n'importe où dans le code

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

Comment lisons-nous la variable ENV dans config.yml, ma configuration est la même .. j'ai ajouté une variable dans bashrc et j'essaie de la lire dans config.yml en utilisant la clé: <% = ENV [URL]%> ... this ne fonctionne pas
shiva

@shiva Regardez dans le gem Figaro pour les variables ENV. Cette configuration de configuration concerne les valeurs qui n'ont pas besoin d'être masquées du contrôle de code source.
Shadoath

17

Je voulais juste mettre à jour ceci pour les derniers trucs sympas dans Rails 4.2 et 5, vous pouvez maintenant le faire dans n'importe lequel de vos config/**/*.rbfichiers:

config.x.whatever = 42

(et c'est un littéral xlà-dedans, c'est-à-dire. le config.x.littéralement doit être ça, et ensuite vous pouvez ajouter ce que vous voulez après le x)

... et cela sera disponible dans votre application en tant que:

Rails.configuration.x.whatever

Pour en savoir plus: http://guides.rubyonrails.org/configuring.html#custom-configuration


3
Juste une clarification qui a initialement causé un problème pour moi; le x n'est pas un espace réservé pour tout ce que vous voulez mettre, il doit vraiment être la lettrex .
tobinibot

Excellent point @tobinibot - J'ai ajouté cette clarification à ma réponse, merci.
smathy

Intéressant que les guides ne mentionnent en fait pas le `` x '', mais je peux attester qu'il est toujours nécessaire à partir de Rails 5.0
Don

Tu as raison Don, c'est bizarre - je suis sûr que ça le disait.
smathy

1
À partir de la documentation courante sur les rails: 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). Source: guides.rubyonrails.org/configuring.html#custom-configuration
David Gay

6

Juste quelques informations supplémentaires sur ce sujet:

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

".with_indifferent_access" vous permet d'accéder aux valeurs du hachage à l'aide d'une clé de chaîne ou d'une clé de symbole équivalente.

par exemple.
APP_CONFIG['audiocast_uri_format'] => 'http://blablalba/blabbitybla/yadda' APP_CONFIG[:audiocast_uri_format] => 'http://blablalba/blabbitybla/yadda'

C'est purement pratique, mais je préfère que mes clés soient représentées sous forme de symboles.


5

J'utilise quelque chose de similaire à John pour Rails 3.0 / 3.1, mais je dois d'abord analyser le fichier par erb:

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

Cela me permet d'utiliser ERB dans ma configuration si j'en ai besoin, comme lire l'url de redistogo d'heroku:

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

2
Je ne pense pas que j'en aurais besoin tous les jours, mais c'est une solution vraiment cool pour les moments où vous en avez besoin. Je pense que je changerais le nom de fichier en config.yml.erb pour correspondre à la convention des rails.
Andrew Burns

2

Rails 4

Pour créer un yaml de configuration personnalisé et le charger (et le rendre disponible pour votre application) de la même manière database_configuration.

Créez votre *.yml, dans mon cas, j'avais besoin d'un fichier de configuration redis.

config/redis.yml

default: &default
  host: localhost
  port: 6379

development:
  <<: *default

test:
  <<: *default

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

Puis chargez la configuration

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

Accédez aux valeurs:

Rails.configuration.redis_configuration[Rails.env]semblable à la façon dont vous pouvez avoir accès à votre database.ymlparRails.configuration.database_configuration[Rails.env]


Vous pouvez également vous faire gagner du temps en ne prenant les paramètres de votre environnement actuel, qui sont probablement les seuls dont vous avez besoin de toute façon: Rails.configuration.redis_configuration = YAML.load_file("#{Rails.root}/config/redis.yml")[Rails.env]. Cependant, dans les rails 4.2 et supérieurs, la réponse de smathy est probablement un moyen plus simple.
omnikron

1

En m'appuyant sur la solution élégante d'Omer Aslam, j'ai décidé de convertir les clés en symboles. Le seul changement est:

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

Cela vous permet ensuite de référencer les valeurs par des symboles sous forme de clés, par ex.

AppConfig[:twitter][:key]

Cela me semble plus net.

(Posté comme réponse car ma réputation n'est pas assez élevée pour commenter la réponse d'Omer)



0

voir ma réponse à Où est le meilleur endroit pour stocker les paramètres de l'application: base de données, fichier, code ...?

Une variante de ce que vous aviez en ce sens qu'il s'agit d'une simple référence à un autre fichier. Il voit que environment.rb n'est pas constamment mis à jour et ne contient pas un tas de choses spécifiques à l'application. Bien que ce ne soit pas une réponse spécifique à votre question «est-ce la voie Rails?», Il y aura peut-être une discussion à ce sujet.


0

Je préfère accéder aux paramètres via la pile d'applications globale. J'évite les variables globales excessives dans la portée locale.

config / initialiseurs / myconfig.rb

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

Et accédez-y avec.

MyAppName::Application.myconfig["yamlstuff"]

0

Ma façon de charger les paramètres avant l'initialisation des rails

Vous permet d'utiliser les paramètres dans l'initialisation de Rails et de configurer les paramètres par environnement

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

Vous pouvez obtenir les paramètres de deux manières: Paramètres ['email'] ou Settings.email


0

Ma meilleure façon de personnaliser la configuration, avec un message de relance lorsque setting.yml est manquant.

est chargé à partir d'un initialiseur personnalisé dans config / initializers / 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]

Créez un YAML dans config / setting.yml

development:
  app_id: 433387212345678
  app_secret: f43df96fc4f65904083b679412345678

test:
  app_id: 148166412121212
  app_secret: 7409bda8139554d11173a32222121212

production:
  app_id: 148166412121212
  app_secret: 7409bda8139554d11173a32222121212
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.