¿La mejor manera de crear opciones de configuración personalizadas para mi aplicación Rails?

133

Necesito crear una opción de configuración para mi aplicación Rails. Puede ser igual para todos los entornos. Descubrí que si lo configuro environment.rb, está disponible en mis vistas, que es exactamente lo que quiero ...

environment.rb

AUDIOCAST_URI_FORMAT = http://blablalba/blabbitybla/yadda

Funciona genial.

Sin embargo, estoy un poco incómodo. ¿Es esta una buena forma de hacerlo? ¿Hay alguna manera que sea más moderna?

Ethan
fuente

Respuestas:

191

Para la configuración general de la aplicación que no necesita almacenarse en una tabla de base de datos, me gusta crear un config.ymlarchivo dentro del directorio de configuración . Para su ejemplo, podría verse así:

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

development:
  <<: *defaults

test:
  <<: *defaults

production:
  <<: *defaults

Este archivo de configuración se carga desde un inicializador personalizado en 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 está utilizando Rails 3, asegúrese de no agregar accidentalmente una barra diagonal a su ruta de configuración relativa.

Luego puede recuperar el valor usando:

uri_format = APP_CONFIG['audiocast_uri_format']

Vea este Railscast para más detalles.

John Topley
fuente
1
Es posible que necesite YAML::ENGINE.yamler = 'syck'que esto funcione stackoverflow.com/a/6140900/414220
evanrmurphy
45
Solo para su información, en Rails 3.x necesita reemplazar RAILS_ENVcon Rails.envy RAILS_ROOTcon Rails.root.
JeanMertz
55
Para Rails 3+ debes unirte a la ruta relativa, no absoluta. No prefije el directorio de configuración con una barra inclinada.
wst
10
No estoy seguro de las versiones anteriores, pero en Rails 4.1 puede hacerloRails.application.config.whatever_you_want = YAML.load_file(Rails.root.join('config', 'config.yml'))[Rails.env]
d4rky
2
@ iphone007 de hecho es posible cargar archivos arbitrarios de yaml desde el directorio de configuración. vea la respuesta de smathy a continuación, que en mi opinión ahora debería ser la respuesta aceptada.
omnikron
82

La versión de Rails 3 del código de inicializador es la siguiente (RAILS_ROOT y RAILS_ENV están en desuso)

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

Además, Ruby 1.9.3 usa Psych, que hace que las teclas de combinación distingan entre mayúsculas y minúsculas, por lo que deberá cambiar su archivo de configuración para tenerlo en cuenta, por ejemplo

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

development:
  <<: *DEFAULTS

test:
  <<: *DEFAULTS

production:
  <<: *DEFAULTS
David Burrows
fuente
3
Usted no necesita "#{Rails.root.to_s}"; "#{Rails.root}"trabajos.
David J.
3
Recomiendo en Rails.root.join('config', 'config.yml')lugar de"#{Rails.root.to_s}/config/config.yml"
David J.
2
Y, en lugar de APP_CONFIG, recomiendo usar:AppName::Application.config.custom
David J.
1
David, tus dos primeros comentarios son una buena práctica y enmendaré el código, pero el último lo voy a omitir, ya que esto significa que debes recordar cambiar el nombre de la aplicación cada vez que uses este código.
David Burrows
53

Rieles> = 4.2

Basta con crear un YAMLarchivo en config/el directorio, por ejemplo: config/neo4j.yml.

El contenido de neo4j.ymlpuede ser algo como a continuación (por simplicidad, usé el valor predeterminado para todos los entornos):

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

development:
  <<: *default

test:
  <<: *default

production:
  <<: *default

en config/application.rb:

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

Ahora, su configuración personalizada es accesible como a continuación:

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

Más información

El documento API oficial de Rails describe el config_formétodo como:

Conveniencia para cargar config / foo.yml para el entorno actual de Rails.


Si no quieres usar un yamlarchivo

Como dice la guía oficial de Rails:

Puede configurar su propio código a través del objeto de configuración Rails con una configuración personalizada en la config.xpropiedad.

Ejemplo

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

Estos puntos de configuración están disponibles a través del objeto de configuración:

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

Referencia oficial para el config_formétodo | Guía oficial de rieles

Ali MasudianPour
fuente
25

Paso 1: Crear 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)

Paso 2: Crear config / config.yml

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

development:
  <<: *common

test:
  <<: *common

production:
  <<: *common

Paso 3: obtén constantes en cualquier parte del código

facebook_key = AppConfig.facebook['key']
twitter_key  = AppConfig.twitter['key']
Omer Aslam
fuente
¿Cómo leemos la variable ENV en config.yml, mi configuración es la misma? He agregado una variable en bashrc y estoy tratando de leer eso en config.yml usando la tecla: <% = ENV [URL]%> ... esto no funciona
shiva
@shiva Busque en la gema de Figaro las variables ENV. Esta configuración de configuración es para valores que no necesitan ocultarse del control de origen.
Shadoath
17

Solo quería actualizar esto para las últimas cosas interesantes en Rails 4.2 y 5, ahora puede hacerlo dentro de cualquiera de sus config/**/*.rbarchivos:

config.x.whatever = 42

(y ese es un literal xallí, es decir, config.x.literalmente debe ser eso, y luego puede agregar lo que quiera después del x)

... y esto estará disponible en su aplicación como:

Rails.configuration.x.whatever

Ver más aquí: http://guides.rubyonrails.org/configuring.html#custom-configuration

pequeño
fuente
3
Solo una aclaración que inicialmente me causó un problema; la x no es un marcador de posición para lo que quiera poner, realmente necesita ser la letra x.
tobinibot
Gran punto @tobinibot: he agregado esa aclaración a mi respuesta, gracias.
inteligente
Es interesante que las guías en realidad no mencionen la 'x', pero puedo dar fe de que aún es necesario a partir de Rails 5.0
Don
Tienes razón Don, eso es extraño, estoy seguro de que solía decirlo.
inteligente
1
De los documentos actuales de 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).Fuente: guides.rubyonrails.org/configuring.html#custom-configuration
David Gay
6

Solo información adicional sobre este tema:

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

".with_indifferent_access" le permite acceder a los valores en el hash utilizando una clave de cadena o con una clave de símbolo equivalente.

p.ej.
APP_CONFIG['audiocast_uri_format'] => 'http://blablalba/blabbitybla/yadda' APP_CONFIG[:audiocast_uri_format] => 'http://blablalba/blabbitybla/yadda'

Es una cuestión de conveniencia, pero prefiero que mis teclas se representen como símbolos.

Foomip
fuente
5

Utilizo algo similar a John para Rails 3.0 / 3.1, pero primero heb analizar el archivo:

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

Esto me permite usar ERB en mi configuración si es necesario, como leer la url de redistogo de heroku:

production:
  <<: *default
  redis:                  <%= ENV['REDISTOGO_URL'] %>
Jack Chu
fuente
2
No creo que necesite esto todos los días, pero esta es una solución realmente genial para esos momentos en que lo necesitas. Creo que cambiaría el nombre del archivo a config.yml.erb para que coincida con la convención de rieles.
Andrew Burns
2

Rails 4

Para crear una configuración personalizada yaml y cargarla (y ponerla a disposición de su aplicación) similar a cómo database_configuration.

Crea tu *.yml, en mi caso necesitaba un archivo de configuración de redis.

config/redis.yml

default: &default
  host: localhost
  port: 6379

development:
  <<: *default

test:
  <<: *default

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

Luego cargue la configuración

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

Acceda a los valores:

Rails.configuration.redis_configuration[Rails.env]a semejante cómo se puede tener acceso a su database.ymlporRails.configuration.database_configuration[Rails.env]

twmulloy
fuente
También podría ahorrar algún tiempo tomando solamente la configuración de su entorno actual, que son probablemente los únicos que de todos modos necesita: Rails.configuration.redis_configuration = YAML.load_file("#{Rails.root}/config/redis.yml")[Rails.env]. Sin embargo, en los rieles 4.2 y superiores, la respuesta de smathy es probablemente una forma más sencilla de hacerlo.
omnikron
1

Partiendo de la elegante solución de Omer Aslam, decidí convertir las teclas en símbolos. El único cambio es:

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

Esto le permite luego hacer referencia a valores mediante símbolos como teclas, por ejemplo

AppConfig[:twitter][:key]

Esto me parece más ordenado a mis ojos.

(Publicado como respuesta ya que mi reputación no es lo suficientemente alta como para comentar la respuesta de Omer)

Kitebuggy
fuente
0

Me gusta simpleconfig . Le permite tener una configuración por entorno.

Jerry Cheung
fuente
0

Prefiero acceder a la configuración a través de la pila global de aplicaciones. Evito el exceso de variables globales en el ámbito local.

config / initializers / myconfig.rb

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

Y accede a él con.

MyAppName::Application.myconfig["yamlstuff"]
6 pies Dan
fuente
0

Mi forma de cargar la configuración antes de que Rails se inicialice

Le permite usar la configuración en la inicialización de Rails y configurar los ajustes por entorno

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

Puede obtener la configuración de dos maneras: Configuración ['correo electrónico'] o Configuración.email

greenif
fuente
0

Mi mejor forma de configuración personalizada, con un mensaje de aumento cuando falta setting.yml.

se carga desde un inicializador personalizado en 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]

Cree un YAML en 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 Austria
fuente