2011-09-22 14 views
6

Mi webapp necesita encriptar los datos de la sesión. Lo que configuro es:Rails 3.1: cómo ejecutar un inicializador solo para la aplicación web (rails server/unicorn/etc)

config/initializers/encryptor.rb: 

require 'openssl' 
require 'myapp/encryptor' 

MyApp::Encryptor.config[ :random_key ] = OpenSSL::Random.random_bytes(128) 
Session.delete_all 

app/models/session.rb: 

require 'attr_encrypted' 

class Session < ActiveRecord::Base 
    attr_accessible :session_id, :data 
    attr_encryptor :data, :key => proc { MyApp::Encryptor.config[ :random_key ] }, :marshal => true 

    # Rest of model stuff 
end 

Todo funciona muy bien y mantiene los datos de la sesión seguros. Este es el problema: cuando ejecuto mis tareas personalizadas de rake, carga el inicializador y borra todas las sesiones. ¡No está bien!

¿Qué puedo poner en mi inicializador para asegurarme de que SOLO se ejecuta para la inicialización de la webapp? O bien, ¿qué puedo poner en mi inicializador para que NO se ejecute para tareas de rake?

Actualización: Bien, lo que he hecho por el momento es agregar MYAPP_IN_RAKE = true unless defined? MYAPP_IN_RAKE a mi archivo .rake. Y luego en mi inicializador lo hago:

unless defined?(MYAPP_IN_RAKE) && MYAPP_IN_RAKE 
    # Web only initialization 
end 

Parece que funciona. Pero estoy abierto a otras sugerencias.

+0

Esto parece obligado a morder en otras formas en el futuro. Cada vez que reinicie el servidor, perderá todas sus sesiones (lo que parece ser el comportamiento previsto), pero eso incluye que el servidor se autocalifique usando demasiada memoria, haciendo que la solicitud se ejecute demasiado tiempo, etc. –

+0

I Entiendo las desventajas, pero creo que vale la pena. La aplicación se reinicia restablecer sesiones: aceptable. Demasiada memoria o demasiado tiempo de una solicitud? En unicornio, estas situaciones solo deberían ocurrir en un proceso de trabajo. Y como configuré 'preload_app = true', la inicialización solo ocurre en el maestro. Entonces, unicornio puede reaparecer a los trabajadores sin causar una reinicialización. – sbutler

+0

Posible duplicado de [los inicializadores de Rails 3 que se ejecutan solo en \ 'rails server \' y no \ 'rails generate \ ', etc] (http://stackoverflow.com/questions/8660019/rails-3-initializers-that- run-only-on-rails-server-and-not-rails-generate-e) – davmac

Respuesta

8

Es posible realizar una modificación en su aplicación en `config/application.rb' como esto:

module MyApp 
    def self.rake? 
    [email protected] 
    end 

    def self.rake=(value) 
    @rake = !!value 
    end 

Luego, en su Rakefile deberá añadir esto:

MyApp.rake = true 

Es agradable use métodos en lugar de constantes ya que a veces prefiere cambiarlos o redefinirlos más tarde. Además, no contaminan el espacio de nombres raíz.

Aquí hay un script de ejemplo config/initializers/rake_environment_test.rb:

if (MyApp.rake?) 
    puts "In rake" 
else 
    puts "Not in rake" 
end 

La naturaleza programable del Rakefile que ofrece una gran flexibilidad.

+0

OK, me gusta esto. Cambié el setter a '@rake = !! value a menos que esté definido? @ rake' para asegurarse de que solo se establezca una vez. Luego, también agregué a environment.rb 'MyApp.rake = false'.¿Suena razonable? – sbutler

+0

¿Por qué te preocuparía configurarlo solo una vez? Una mejor práctica que simplemente ignorar el conjunto duplicado es, al menos, emitir una advertencia, o mejor, lanzar una excepción para que pueda rastrear el origen del problema. – tadman

+0

Supongo que me preocupa que, mientras se ejecuta como código de webapp, el Rakefile se cargue de alguna manera. Estoy pensando simétricamente: como rake, el entorno de webapp está cargado, por lo que también debería manejar el caso en el que la aplicación web y el rake se carguen. – sbutler

2

Hay otro trabajo en torno a:

unless ENV["RAILS_ENV"].nil? || ENV["RAILS_ENV"] == 'test' 

Al iniciar con el rastrillo su ENV [ "RAILS_ENV"] será igual a cero. La prueba para 'prueba' es evitar ejecutar cuando se usa rspec.

Sé que se considera que usar Rails.env pero devuelve "desarrollo" cuando no se inicializa.

http://apidock.com/rails/Rails/env/class

# File railties/lib/rails.rb, line 55 
def env 
    @_env ||= ActiveSupport::StringInquirer.new(ENV["RAILS_ENV"] 
    || ENV["RACK_ENV"] || "development") 
end 
+0

¡Gracias! ¡Justo lo que necesitaba! –

Cuestiones relacionadas