2010-11-10 6 views
24

Estoy tratando de agregar dos opciones de configuración adicionales a mi application.rb para que pueda leerlas en los controladores.Acceso a config desde application.rb en Controller (Rails 3)

# Extra 
config.twitter.key = 'foo' 
config.twitter.secret = 'bar' 

Estoy tratando de acceder a ellos utilizando tres métodos sugeridos:

self.config.twitter.key # Should be extended through ApplicationController Base 
config.twitter.key # Inherited but with different syntax 
CONFIG['twitter']['key'] #some massive magical array that apparently exists somewhere 

Todos ellos me dan diferentes tipos de error cuando ellos pasan a través del método de "depuración", Ej:

debug self.config.twitter.key # undefined method `key' for nil:NilClass 

Entonces, ¿qué está pasando?

Respuesta

45

Creo que tienes una idea ligeramente incorrecta detrás de lo que sus expectativas para el config/application.rb se le proporciona. Las clases propias de ActiveRecord :: Base y ActiveController :: Base usan la clase Rails :: Application :: Configuration que está configurada en config/application.rb. Los atributos no están disponibles en las clases que descienden de cualquiera de las clases Base, ni sus clases propias. Esta es la razón por la cual se están ejecutando errores en ApplicationController.

En general, hay dos formas de realizar inicializaciones de configuración en una aplicación de Rails. La primera forma es crear un módulo de configuración y valores de carga luego en ella a través de inicializador:

En primer lugar, crear un módulo Twiter Config:

#lib/twitter_config.rb 
module TwitterConfig 
    def self.config 
    @@config ||= {} 
    end 

    def self.config=(hash) 
    @@config = hash 
    end 
end 

Crear un archivo de configuración YAML:

# config/twitter.yaml 
development: &base 
    key: "foo" 
    secret: "bar" 

test: 
<<: *base 
key: "foo2" 

production: 
    <<: *base 
    secret: "barbar" 

Alternativamente, si no tiene la intención de agregar config/twitter.yaml a su SCM, puede omitir esto y configurar la clave y el secreto a través de variables de entorno. Esta sería la solución sugerida para una aplicación con un repositorio de SCM público desplegado en Heroku.

A continuación, cargar y configurar el valor a través de un inicializador:

#config/initializers/01_twitter.rb 
require 'twitter_config' 

TwitterConfig.config = YAML.load_file("config/config.yml")[Rails.env].symbolize_keys 

Por lo general es una buena práctica para numerar los archivos de inicializador como carriles de los cargará con el fin de acuerdo con su nombre de archivo. Si está inicializando un almacén de datos y eso es crítico para otros pasos, entonces necesita el número más bajo. Como alternativa, si está utilizando variables de entorno, este sería el archivo de inicio:

#config/initializers/01_twitter.rb 
require 'twitter_config' 

TwitterConfig.config[:key] = ENV['twitter_config_key'] 
TwitterConfig.config[:secret] = ENV['twitter_config_secret'] 

A lo largo de la aplicación Rails, ahora tiene acceso a los valores de configuración con TwitterConfig.config [: clave] & TwitterConfig.config [: secreto]. Puede incluir el módulo también, solo tenga cuidado con los conflictos.

También puede simplemente cargar los valores como una constante global. Se siente un poco feo para mí, sin embargo:

#config/application.rb 
TWITTER_CONFIG = YAML.load_file("config/twitter.yaml")[Rails.env] 
+2

Bloody buena respuesta, muchas gracias. –

+0

¡Reajustó las variables a cero en el servidor de desarrollo! –

+0

Tengo algunos problemas para hacer que esto funcione en una aplicación de Rails 3.1 con Ruby 1.9.2-p180. En mi aplicación, si tuviera que llamar a TwitterConfig.method, simplemente me daría un error. Sin embargo, si inspecciono TwitterConfig.instance_methods, puedo ver claramente los métodos definidos. – Emerson

5

Es posible que desee considerar el uso de un enfoque de archivo yaml.

En application.rb

CONFIG = YAML.load_file("config/config.yml")[Rails.env] 

En config/config.yml

development: &base_config 
    twitter_key = "foo" 
    twitter_secret = "bar" 

test: 
    <<: *base_config 
    twitter_key = "foo2" 

production: 
    <<: *base_config 
    twitter_secret = "barbar" 

Misma utilización que antes, con atributos definibles en un nivel medio con sobrecarga.

CONFIG['twitter_key'] 
+0

Eso se ve muy bien, pero ¿cómo puedo leer esos valores en application.rb. ¿No es eso para lo que son? –

-1

Sólo hay que poner un archivo en config/initializers/ como app_config.rb Si utiliza ENV constante puede implementar más adelante fácilmente a Heroku establecer los valores con el comando heroku config:add twitter_key=mypublickey.

Algo como esto:

## config/initializers/app_config.rb 
unless Rails.env.production? 
    ENV['twitter_key'] = 'foo' 
    ENV['twitter_secret'] = 'bar' 
end 

a mantener su producción teclas de control de revisión y no necesitan a driblar con YAML-archivos.

0

Una pequeña actualización a la respuesta aceptada aquí: Accessing config from application.rb in Controller (Rails 3)

Los métodos dentro del módulo debe ser TwitterConfig métodos de clase (o métodos de módulo, si lo prefiere de esa manera). No pueden ser métodos de instancia.

Perdón por poner esto en una respuesta, pero no pude encontrar la manera de comentar esa respuesta.

13

He intentado esto y parece estar funcionando, puede utilizar :: Rails.application.config.

Por ejemplo, yo estoy usando para obtener la correcta time_zone establecido en la aplicación de esta manera:

Rails.application.config.time_zone

lo encontré gracias al menos- carriles código: https://github.com/metaskills/less-rails/blob/master/lib/less/rails/helpers.rb

Así se puede declarar esto en su application.rb o en cualquier archivo ambiente:

config.twitter_key = 'foo'

Y luego leyó al igual que cualquier parte del código:

Rails.application.config.twitter_key

+0

Los dos dos puntos ('::') no parecen ser necesarios. –

Cuestiones relacionadas