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é?

Ethan
la source

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.

John Topley
la source
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
David Burrows
la source
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

Ali MasudianPour
la source
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']
Omer Aslam
la source
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

smathy
la source
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.

foomip
la source
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'] %>
Jack Chu
la source
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]

twmulloy
la source
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)

Kitebuggy
la source
0

J'aime simpleconfig . Il vous permet d'avoir une configuration par environnement.

Jerry Cheung
la source
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.

Straff
la source
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"]
6 pieds Dan
la source
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

greenif
la source
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
Marcelo Autriche
la source