¿Es posible establecer variables ENV para el entorno de desarrollo de Rails en mi código?

Sé que puedo configurar mis variables ENV en bash vía

export admin_password = "secret" 

Pero, ¿hay alguna manera de hacerlo en el código fuente de mis rails en algún lugar? Mi primer bash fue algo así en environment/development.rb

 ENV['admin_password'] = "secret" 

Pero no funcionó. ¿Hay alguna forma de hacer esto?

[Actualizar]

Si bien la solución en “respuesta anterior” funcionará para problemas generales, esta sección es para responder a su pregunta específica después de la aclaración de su comentario.

Debería poder establecer variables de entorno exactamente como las especifica en su pregunta. Como ejemplo, tengo una aplicación Heroku que usa autenticación básica HTTP.

 # app/controllers/application_controller.rb class ApplicationController < ActionController::Base protect_from_forgery before_filter :authenticate def authenticate authenticate_or_request_with_http_basic do |username, password| username == ENV['HTTP_USER'] && password == ENV['HTTP_PASS'] end end end # config/initializers/dev_environment.rb unless Rails.env.production? ENV['HTTP_USER'] = 'testuser' ENV['HTTP_PASS'] = 'testpass' end 

Entonces en tu caso usarías

 unless Rails.env.production? ENV['admin_password'] = "secret" end 

¡No olvide reiniciar el servidor para que la configuración se vuelva a cargar!

[Respuesta anterior]

Para la configuración de toda la aplicación, puede considerar una solución como la siguiente:

Cree una config/application.yml archivo config/application.yml con un hash de opciones a las que quiera acceder:

 admin_password: something_secret allow_registration: true facebook: app_id: application_id_here app_secret: application_secret_here api_key: api_key_here 

Ahora, cree el archivo config/initializers/app_config.rb e incluya lo siguiente:

 require 'yaml' yaml_data = YAML::load(ERB.new(IO.read(File.join(Rails.root, 'config', 'application.yml'))).result) APP_CONFIG = HashWithIndifferentAccess.new(yaml_data) 

Ahora, en cualquier lugar de su aplicación, puede acceder a APP_CONFIG[:admin_password] , junto con todos sus otros datos. (Tenga en cuenta que dado que el inicializador incluye ERB.new , su archivo YAML puede contener marcado ERB).

Nunca codifique información confidencial (credenciales de cuenta, contraseñas, etc.) . En su lugar, cree un archivo para almacenar esa información como variables de entorno (pares de clave / valor) y excluya ese archivo de su sistema de gestión de código fuente. Por ejemplo, en términos de Git (sistema de gestión de código fuente), excluya ese archivo agregándolo a. gitignore :

 -bash> echo '/config/app_environment_variables.rb' >> .gitignore 

/config/app_environment_variables.rb

 ENV['HTTP_USER'] = 'devuser' ENV['HTTP_PASS'] = 'devpass' 

Además, agregue las siguientes líneas a /config/environment.rb , entre la línea require y la línea Application.initialize :

 # Load the app's custom environment variables here, so that they are loaded before environments/*.rb app_environment_variables = File.join(Rails.root, 'config', 'app_environment_variables.rb') load(app_environment_variables) if File.exists?(app_environment_variables) 

¡Eso es!

Como dice el comentario anterior, al hacer esto cargará sus variables de entorno antes de environments/*.rb , lo que significa que podrá referirse a sus variables dentro de esos archivos (ej. environments/production.rb ). Esta es una gran ventaja sobre poner su archivo de variables de entorno dentro de /config/initializers/ .

Dentro de app_environment_variables.rb no es necesario distinguir entornos en cuanto a desarrollo o producción porque nunca se comprometerá este archivo en su sistema de gestión de código fuente, por lo tanto, es para el contexto de desarrollo por defecto. Pero si necesita establecer algo especial para el entorno de prueba (o para ocasiones en las que prueba el modo de producción localmente ), simplemente agregue un bloque condicional debajo de todas las demás variables:

 if Rails.env.test? ENV['HTTP_USER'] = 'testuser' ENV['HTTP_PASS'] = 'testpass' end if Rails.env.production? ENV['HTTP_USER'] = 'produser' ENV['HTTP_PASS'] = 'prodpass' end 

Siempre que actualice app_environment_variables.rb , reinicie el servidor de la aplicación. Asumiendo que está usando rails server como Apache / Passenger o rails server :

 -bash> touch tmp/restart.txt 

En su código, consulte las variables de entorno de la siguiente manera:

 def authenticate authenticate_or_request_with_http_basic do |username, password| username == ENV['HTTP_USER'] && password == ENV['HTTP_PASS'] end end 

Tenga en cuenta que dentro de app_environment_variables.rb debe especificar booleanos y números como cadenas (por ejemplo, ENV['SEND_MAIL'] = 'false' no simplemente false , y ENV['TIMEOUT'] = '30' no solo 30 ), de lo contrario obtendrá los errores can't convert false into String y can't convert Fixnum into String , respectivamente.

Almacenar y compartir información sensible

El nudo final para empatar es: ¿cómo compartir esta información sensible con sus clientes y / o socios? A los fines de la continuidad del negocio (es decir, cuando te golpea una estrella fugaz, ¿cómo reanudarán tus clientes y / o socios las operaciones completas del sitio?), Tus clientes y / o socios deben conocer todas las credenciales requeridas por tu aplicación . Enviar por correo electrónico / Skyping estas cosas es inseguro y conduce al desorden. Almacenarlo en documentos de Google compartidos no es malo (si todos usan https), pero una aplicación dedicada a almacenar y compartir pequeñas cosas como contraseñas sería ideal.

Cómo establecer variables de entorno en Heroku

Si tienes un solo entorno en Heroku:

 -bash> heroku config:add HTTP_USER='herouser' -bash> heroku config:add HTTP_USER='heropass' 

Si tienes múltiples entornos en Heroku:

 -bash> heroku config:add HTTP_USER='staguser' --remote staging -bash> heroku config:add HTTP_PASS='stagpass' --remote staging -bash> heroku config:add HTTP_USER='produser' --remote production -bash> heroku config:add HTTP_PASS='prodpass' --remote production 

Foreman y .env

Muchos desarrolladores usan Foreman (instalado con Heroku Toolbelt ) para ejecutar sus aplicaciones localmente (en lugar de usar rails server como Apache / Passenger o rails server ). Foreman y Heroku usan Procfile para declarar qué comandos ejecuta tu aplicación , por lo que la transición de dev local a Heroku es perfecta en ese aspecto. Uso Foreman y Heroku en todos los proyectos de Rails, así que esta conveniencia es genial. Pero esta es la /.env . Foreman carga las variables de entorno almacenadas en /.env través de dotenv, pero desafortunadamente dotenv esencialmente solo analiza el archivo para key=value pares key=value ; esos pares no se convierten en variables allí mismo, entonces no puedes referirte a las variables ya establecidas (para mantener las cosas SECAS), ni puedes hacer “Ruby” allí (como se señaló anteriormente con los condicionales), que puedes hacer en /config/app_environment_variables.rb . Por ejemplo, en términos de mantener las cosas SECAS, a veces hago cosas como esta:

 ENV['SUPPORT_EMAIL']='Company Support ' ENV['MAILER_DEFAULT_FROM'] = ENV['SUPPORT_EMAIL'] ENV['MAILER_DEFAULT_TO'] = ENV['SUPPORT_EMAIL'] 

Por lo tanto, utilizo Foreman para ejecutar mis aplicaciones localmente, pero no uso su archivo .env para cargar variables de entorno; más bien uso Foreman junto con el enfoque /config/app_environment_variables.rb descrito anteriormente.

La forma en que bash hacer esto en mi pregunta realmente funciona.

 # environment/development.rb ENV['admin_password'] = "secret" 

Solo tuve que reiniciar el servidor. ¡Pensé en reload! en la consola Rails sería suficiente, pero también tuve que reiniciar el servidor web.

Estoy escogiendo mi propia respuesta porque siento que este es un mejor lugar para poner y establecer las variables ENV

Aparte de las soluciones aquí, hay alternativas más limpias si está usando ciertos servidores de desarrollo.

Con el Capataz de Heroku, puede crear variables de entorno por proyecto en un archivo .env :

 ADMIN_PASSOWRD="secret" 

Con Pow , puedes usar un archivo .powenv :

 export ADMIN_PASSOWRD="secret" 

Creo que la mejor manera es almacenarlos en algún archivo yml y luego cargar ese archivo usando este comando en el archivo intializer

 APP_CONFIG = YAML.load_file("#{Rails.root}/config/CONFIG.yml")[Rails.env].to_hash 

puede acceder fácilmente a las variables de configuración relacionadas con el entorno.

Su estructura de valor de clave de archivo Yml:

 development: app_key: 'abc' app_secret: 'abc' production: app_key: 'xyz' app_secret: 'ghq' 

El entorno del sistema y el entorno de los Rails son cosas diferentes. ENV permite trabajar con el entorno de los Rails, pero si lo que quieres hacer es cambiar el entorno del sistema en tiempo de ejecución, puedes rodear el comando con barras de refuerzo.

 # ruby code `export admin_password="secret"` # more ruby code 

Script para cargar el archivo .env personalizado: agregue las siguientes líneas a /config/environment.rb , entre la línea require y la línea Application.initialize :

 # Load the app's custom environment variables here, so that they are loaded before environments/*.rb app_environment_variables = File.join(Rails.root, 'config', 'local_environment.env') if File.exists?(app_environment_variables) lines = File.readlines(app_environment_variables) lines.each do |line| line.chomp! next if line.empty? or line[0] == '#' parts = line.partition '=' raise "Wrong line: #{line} in #{app_environment_variables}" if parts.last.empty? ENV[parts.first] = parts.last end end 

Y config/local_environment.env (querrá .gitignore ) se verá así:

 # This is ignored comment DATABASE_URL=mysql2://user:psw@0.0.0:3307/database RACK_ENV=development 

(Basado en la solución de @ user664833)