Necesito limpiar la sesión después de cierto tiempo rails.
Por especificación >>,  ésto se puede hacer con

reset_session

pero no me parece buena práctica ligar el fin de la sesión a una acción en específico: ¿qué pasa si el usuario abandona la app a mitad de camino?
Si implementamos la sesión en la cookie ésto no nos preocupa, ya que no nos supone memoria extra…
Pero en mi app necesito borrar los archivos que haya subido de mi servidor, o sino me iré llenando de archivos que no son de nadie.
Además, así le doy la opción al usuario de volver atrás e intentar varias veces con el mismo archivo, sin que tenga que subirlo a cada vez.

filtro

Googleando un poco >>, salta a la vista que necesitaré usar filtros para lograrlo >>

En app/controllers/app_controller.rb escribiremos un before_filter que antes de cada request guarde registro de cuando fue la última vez que se vió al usuario

#todos los controllers heredan de éste
#por tanto este filtro se aplica a todos los request
class ApplicationController < ActionController::Base
before_filter :last_seen
private
  def last_seen
    if session[:last_seen] < 20.minutes.ago then
      #mi lógica
      reset_session
    end
      session[:last_seen] = Time.now
  end
end

Aquí, antes de reset_session, puedo ejecutar la lógica que quiero de limpiar directorios, etc.

whenever

Éso soluciona el fin de sesión siempre y cuando el usuario vuelva – de hecho, ¿no debiera entonces extendérsela? – Lo importante es ir limpiando los directorios si el usuario nunca más se vió.
Ésto lo haremos con una gema llamada whenever – que de hecho creo que ya viene en rails (scheduler.rb?): no, no está – que ofrece una sintaxis ruby para configurar el cron del sistema.
Simplemente la agregamos en el Gemfile

gem 'whenever'

y luego de

 bundle install

ejecutamos

 wheneverize

para crear config/schedule.rb donde…

Ahora, como necesito los datos de la sesión para limpiar los directorios de las que están expiradas, no me sirve que las sesiones se guarden en las cookies – como es el default – sino que tener acceso a ella desde el tarea que ejecutaré periódicamente.

active_record_store

Entonces requiero que las sesiones se guarden en la base de datos. Para ésto, modificamos el archivo config/initializers/session_store.rb

MiApp::Application.config.session_store :active_record_store

y luego ejecutamos

rails generate session_migration

para generar la migración que crea la tabla de sesión y

rake db:migrate

para crearla.

rake

Con éstose podré usar whenever para ejecutar un rake (o un método de un modelo usando rails runner). Utilizaré la primera de las opciones porque me parece más consistente – justamente es una tarea lo que quiero hacer.

En lib/tasks creo un un archivo cuyo nombre termine en .rake para que sea incluído al Rakefile.
Dentro defino una task así

 namespace :db do
 namespace :sessions do
 desc "Limpia los directorios de las sesiones expiradas"
 task :expire => :environment do #tiene acceso a Rails
 Rails.logger.info "Limpiando sesiones..."#logueo
 tiempo = 10.minutes.ago.to_s(:db)
 sql = "DELETE FROM sessions WHERE updated_at < "+tiempo
 ActiveRecord::Base.connection.execute(sql)#borro sesiones expiradas
 end
 end
 end

Si queremos ejecutarlo, de acuerdo a sus <em>namespace</em>, podemos llamarlo

rake db:sessiones:expire

Y es el que ejecutaremos desde el archivo scheduler.rb que vimos más arriba

every 1.days do
rake "db:sessions:expire"
end

Para que el cron se haga efectivo, ejecutamos

 whenever -w -s environment=development

(ojo con la opción -s, donde seteamos el RAILS_ENV a development – o el que se esté usando – ya que sino actuará en otra base de datos)
y efectivamente estaremos limpiando las sesiones periódicamente.

Este sitio utiliza cookies.    Leer más
Privacidad