Der beste Weg, um benutzerdefinierte Konfigurationsoptionen für meine Rails-App zu erstellen?

133

Ich muss eine Konfigurationsoption für meine Rails-Anwendung erstellen. Dies kann für alle Umgebungen gleich sein. Ich habe festgestellt, dass environment.rbes in meinen Ansichten verfügbar ist , wenn ich es einstelle. Genau das möchte ich ...

environment.rb

AUDIOCAST_URI_FORMAT = http://blablalba/blabbitybla/yadda

Funktioniert super.

Ich bin jedoch etwas unruhig. Ist das ein guter Weg, es zu tun? Gibt es einen Weg, der angesagter ist?

Ethan
quelle

Antworten:

191

Für die allgemeine Anwendungskonfiguration, die nicht in einer Datenbanktabelle gespeichert werden muss, möchte ich eine config.ymlDatei im Konfigurationsverzeichnis erstellen . In Ihrem Beispiel könnte es so aussehen:

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

development:
  <<: *defaults

test:
  <<: *defaults

production:
  <<: *defaults

Diese Konfigurationsdatei wird von einem benutzerdefinierten Initialisierer in config / initializers geladen :

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

Wenn Sie Rails 3 verwenden, stellen Sie sicher, dass Sie Ihrem relativen Konfigurationspfad nicht versehentlich einen führenden Schrägstrich hinzufügen.

Sie können den Wert dann abrufen mit:

uri_format = APP_CONFIG['audiocast_uri_format']

Weitere Informationen finden Sie in diesem Railscast .

John Topley
quelle
1
Möglicherweise muss YAML::ENGINE.yamler = 'syck'dies funktionieren. Stackoverflow.com/a/6140900/414220
evanrmurphy
45
Eine gerade FYI, in Rails 3.x Sie ersetzen müssen RAILS_ENVmit Rails.envund RAILS_ROOTmit Rails.root.
JeanMertz
5
Für Rails 3+ sollten Sie sich dem relativen Pfad anschließen, nicht dem absoluten. Stellen Sie dem Konfigurationsverzeichnis keinen Schrägstrich voran.
wst
10
Nicht sicher über frühere Versionen, aber in Rails 4.1 können Sie tunRails.application.config.whatever_you_want = YAML.load_file(Rails.root.join('config', 'config.yml'))[Rails.env]
d4rky
2
@ iphone007 Es ist tatsächlich möglich, beliebige Yaml-Dateien aus dem Konfigurationsverzeichnis zu laden. siehe smathys Antwort, die meiner Meinung nach jetzt die akzeptierte Antwort sein sollte.
Omnikron
82

Die Rails 3-Version des Initialisierungscodes lautet wie folgt (RAILS_ROOT & RAILS_ENV sind veraltet).

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

Außerdem verwendet Ruby 1.9.3 Psych, wodurch bei Zusammenführungsschlüsseln zwischen Groß- und Kleinschreibung unterschieden wird. Sie müssen daher Ihre Konfigurationsdatei ändern, um dies zu berücksichtigen, z

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

development:
  <<: *DEFAULTS

test:
  <<: *DEFAULTS

production:
  <<: *DEFAULTS
David Burrows
quelle
3
Du brauchst nicht "#{Rails.root.to_s}"; "#{Rails.root}"funktioniert.
David J.
3
Ich empfehle Rails.root.join('config', 'config.yml')anstelle von"#{Rails.root.to_s}/config/config.yml"
David J.
2
Und anstelle von APP_CONFIG empfehle ich:AppName::Application.config.custom
David J.
1
David, deine ersten beiden Kommentare sind bewährte Methoden und ich werde den Code ändern, aber den letzten werde ich weglassen, da dies bedeutet, dass du daran denken musst, den AppName jedes Mal zu ändern, wenn du diesen Code verwendest.
David Burrows
53

Schienen> = 4.2

Erstellen Sie einfach eine YAMLDatei im config/Verzeichnis, zum Beispiel : config/neo4j.yml.

Der Inhalt von neo4j.ymlkann wie folgt aussehen (Der Einfachheit halber habe ich für alle Umgebungen die Standardeinstellung verwendet):

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

Jetzt ist Ihre benutzerdefinierte Konfiguration wie folgt zugänglich:

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

Mehr Info

Das offizielle API-Dokument von Rails beschreibt die config_forMethode wie folgt :

Bequemes Laden von config / foo.yml für die aktuelle Rails-Umgebung.


Wenn Sie keine yamlDatei verwenden möchten

Wie der offizielle Leitfaden von Rails sagt:

Sie können Ihren eigenen Code über das Rails-Konfigurationsobjekt mit benutzerdefinierter Konfiguration unter der config.xEigenschaft konfigurieren .

Beispiel

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

Diese Konfigurationspunkte sind dann über das Konfigurationsobjekt verfügbar:

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

Offizielle Referenz für config_forMethode | Offizieller Rails Guide

Ali MasudianPour
quelle
25

Schritt 1: Erstellen Sie 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)

Schritt 2: Erstellen Sie config / config.yml

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

development:
  <<: *common

test:
  <<: *common

production:
  <<: *common

Schritt 3: Holen Sie sich Konstanten an eine beliebige Stelle im Code

facebook_key = AppConfig.facebook['key']
twitter_key  = AppConfig.twitter['key']
Omer Aslam
quelle
Wie lesen wir die ENV-Variable in config.yml? Meine Konfiguration ist dieselbe. Ich habe eine Variable in bashrc hinzugefügt und versuche, diese in config.yml mit dem Schlüssel zu lesen: <% = ENV [URL]%> ... this funktioniert nicht
Shiva
@shiva Suchen Sie im Figaro-Juwel nach ENV-Variablen. Dieses Konfigurationssetup gilt für Werte, die nicht vor der Quellcodeverwaltung verborgen werden müssen.
Shadoath
17

Ich wollte dies nur für die neuesten coolen Sachen in Rails 4.2 und 5 aktualisieren. Sie können dies jetzt in jeder Ihrer config/**/*.rbDateien tun :

config.x.whatever = 42

(und das ist ein wörtliches xWort, dh das config.x.muss buchstäblich so sein, und dann können Sie nach dem hinzufügen, was Sie wollenx )

... und dies wird in Ihrer App verfügbar sein als:

Rails.configuration.x.whatever

Weitere Informationen finden Sie hier: http://guides.rubyonrails.org/configuring.html#custom-configuration

smathy
quelle
3
Nur eine Klarstellung, die mir anfangs ein Problem bereitete; Das x ist kein Platzhalter für alles, was Sie eingeben möchten, es muss wirklich der Buchstabe sein x.
Tobinibot
Toller Punkt @tobinibot - Ich habe diese Klarstellung zu meiner Antwort hinzugefügt, danke.
Smathy
Interessant, dass die Guides das 'x' eigentlich nicht erwähnen, aber ich kann bestätigen, dass es ab Rails 5.0
Don
Du hast recht, Don, das ist komisch - ich bin sicher, es hat es früher gesagt.
Smathy
1
Aus den aktuellen Rails-Dokumenten: 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).Quelle : guides.rubyonrails.org/configuring.html#custom-configuration
David Gay
6

Nur ein paar zusätzliche Infos zu diesem Thema:

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

Mit ".with_indifferent_access" können Sie mit einem String-Schlüssel oder einem entsprechenden Symbolschlüssel auf die Werte im Hash zugreifen.

z.B.
APP_CONFIG['audiocast_uri_format'] => 'http://blablalba/blabbitybla/yadda' APP_CONFIG[:audiocast_uri_format] => 'http://blablalba/blabbitybla/yadda'

Rein praktisch, aber ich ziehe es vor, meine Schlüssel als Symbole darzustellen.

Foomip
quelle
5

Ich verwende etwas Ähnliches wie John für Rails 3.0 / 3.1, aber ich muss die Datei zuerst analysieren:

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

Auf diese Weise kann ich ERB in meiner Konfiguration verwenden, wenn dies erforderlich ist, z. B. das Lesen der Redistogo-URL von Heroku:

production:
  <<: *default
  redis:                  <%= ENV['REDISTOGO_URL'] %>
Jack Chu
quelle
2
Ich glaube nicht, dass ich das jeden Tag brauchen würde, aber dies ist eine wirklich coole Lösung für die Zeiten, in denen Sie es brauchen. Ich denke, ich würde den Dateinamen in config.yml.erb ändern, obwohl er der Rails-Konvention entspricht.
Andrew Burns
2

Rails 4

So erstellen Sie ein benutzerdefiniertes Konfigurations-Yaml und laden es (und stellen es Ihrer App zur Verfügung), ähnlich wie database_configuration.

Erstellen Sie Ihre *.yml, in meinem Fall brauchte ich eine Redis-Konfigurationsdatei.

config/redis.yml

default: &default
  host: localhost
  port: 6379

development:
  <<: *default

test:
  <<: *default

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

Laden Sie dann die Konfiguration

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

Greifen Sie auf die Werte zu:

Rails.configuration.redis_configuration[Rails.env]ähnlich wie Sie Zugriff auf Ihre database.ymlvon haben könnenRails.configuration.database_configuration[Rails.env]

Twmulloy
quelle
Sie können sich auch Zeit sparen, indem Sie nur die Einstellungen für Ihre aktuelle Umgebung vornehmen, die vermutlich die einzigen sind, die Sie ohnehin benötigen : Rails.configuration.redis_configuration = YAML.load_file("#{Rails.root}/config/redis.yml")[Rails.env]. In Rails 4.2 und höher ist Smathys Antwort wahrscheinlich ein einfacherer Weg.
Omnikron
1

Aufbauend auf der eleganten Lösung von Omer Aslam habe ich beschlossen, die Schlüssel in Symbole umzuwandeln. Die einzige Änderung ist:

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

Auf diese Weise können Sie Werte durch Symbole als Schlüssel referenzieren, z

AppConfig[:twitter][:key]

Das scheint mir ordentlicher zu sein.

(Als Antwort veröffentlicht, da mein Ruf nicht hoch genug ist, um Omers Antwort zu kommentieren.)

Kitebuggy
quelle
0

Ich mag simpleconfig . Es ermöglicht Ihnen die Konfiguration pro Umgebung.

Jerry Cheung
quelle
0

Siehe meine Antwort auf Wo ist der beste Ort zum Speichern von Anwendungsparametern: Datenbank, Datei, Code ...?

Eine Variation von dem, was Sie darin hatten, dass es ein einfacher Verweis auf eine andere Datei ist. Es sieht, dass environment.rb nicht ständig aktualisiert wird und keinen Haufen app-spezifischer Inhalte enthält. Obwohl es keine konkrete Antwort auf Ihre Frage gibt, ob es der Rails-Weg ist, wird es dort vielleicht eine Diskussion darüber geben.

Straff
quelle
0

Ich bevorzuge den Zugriff auf Einstellungen über den globalen Anwendungsstapel. Ich vermeide übermäßige globale Variablen im lokalen Bereich.

config / initializers / myconfig.rb

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

Und mit darauf zugreifen.

MyAppName::Application.myconfig["yamlstuff"]
6ft Dan
quelle
0

Meine Methode zum Laden von Einstellungen vor der Initialisierung von Rails

Ermöglicht die Verwendung von Einstellungen bei der Rails-Initialisierung und die Konfiguration von Einstellungen pro Umgebung

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

Sie können Einstellungen auf zwei Arten erhalten: Einstellungen ['E-Mail'] oder Einstellungen.email

greenif
quelle
0

Mein bester Weg zur benutzerdefinierten Konfiguration mit Raise-Meldung, wenn settings.yml fehlt.

wird von einem benutzerdefinierten Initialisierer in config / initializers / custom_config.rb geladen

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]

Erstellen Sie eine YAML in config / settings.yml

development:
  app_id: 433387212345678
  app_secret: f43df96fc4f65904083b679412345678

test:
  app_id: 148166412121212
  app_secret: 7409bda8139554d11173a32222121212

production:
  app_id: 148166412121212
  app_secret: 7409bda8139554d11173a32222121212
Marcelo Österreich
quelle