2009-07-08 14 views
9

Siempre me han enseñado que almacenar objetos en una sesión era una mala idea. En su lugar, las ID deben almacenarse para recuperar el registro cuando sea necesario.Almacenar objetos en una sesión en Rails

Sin embargo, tengo una aplicación que me pregunto es una excepción a esta regla. Estoy construyendo una aplicación de tarjeta de memoria, y las palabras que se cuestionan están en una tabla en la base de datos cuyo esquema no cambia. Quiero guardar las palabras que están siendo examinadas en una sesión, para que un usuario pueda terminar donde comenzaron en caso de que pasen a una página separada.

En este caso, ¿es posible guardar estas palabras como objetos en la base de datos? Si es así, ¿por qué? La razón por la que pregunto es porque la prueba está diseñada para moverse rápidamente, y odiaría desperdiciar una llamada a la base de datos para recuperar un registro que nunca cambia en primer lugar. Sin embargo, tal vez haya otros aspectos negativos de una gran sesión de los que no tengo conocimiento.

* Para el registro, he intentado guardarlo en la memoria caché con los métodos de Memcache incorporados en Rails 2.3, pero aparentemente tiene un tamaño máximo por artículo de 1MB.

+0

¿Un tamaño máximo de caché de 1MB? Eso no suena bien. –

+0

Estaba sorprendido como primero, pero estaba teniendo problemas muy extraños hasta que descubrí esto: http://code.google.com/p/memcached/wiki/FAQ#Why_are_items_limited_to_1_megabyte_in_size? Aunque me encantaría solo una forma de almacenarlo en caché, ya que resolvería mi problema. –

+0

¡Oh, es un máximo de 1 MB * por elemento de caché *! He editado tu pregunta para aclarar esa parte. –

Respuesta

25

La razón principal para no almacenar objetos en la sesión es que si la estructura del objeto cambia, obtendrá una excepción. Considere lo siguiente:

class Foo 
    attr_accessor :bar 
end 

class Bar 
end 

foo = Foo.new 
foo.bar = Bar.new 
put_in_session(foo) 

Luego, en una versión posterior del proyecto, cambia el nombre de Bar. Reinicias el servidor e intentas sacar a Foo de la sesión. Cuando intenta deserializar, falla al encontrar Bar y explota.

Parecería que sería fácil evitar este escollo, pero en la práctica, he visto morder a varias personas. Esto se debe a que la serialización de un objeto a veces puede llevar más tiempo de lo que parece de inmediato (este tipo de cosas se supone que es transparente) y, a menos que tenga reglas rigurosas sobre esto, las cosas tenderán a desconcertarse. El motivo por el que normalmente se desaprueba es que es muy común que esto muerda a las personas en ActiveRecord, ya que es bastante común que la estructura de la aplicación cambie con el tiempo y las sesiones se pueden deserializar una semana o más después de que se hayan eliminado. originalmente creado.

Si comprende todo eso y está dispuesto a poner la energía para asegurarse de que su modelo no cambia y no está serializando nada extra, probablemente esté bien. Pero tenga cuidado :)

+0

'cambias el nombre de Bar', ¿puedes ser más específico acerca de este cambio, como un ejemplo? Observamos un comportamiento extraño al almacenar un objeto no tan grande (un grupo de identificadores) en la aplicación rails 4 y no estamos seguros de lo que sucedió. Gracias. – user938363

6

Los rieles tienden a alentar el diseño RESTful, y el uso de sesiones no es muy RESTful. Probablemente haga un recurso de cuestionario que tenga un montón de palabras, así como una palabra actual. De esta forma, cuando vuelvan, sabrán dónde estaban.

Ahora, REST no es todo (dependiendo de con quién hable), pero hay un caso bastante bueno en contra de sesiones grandes. Recuerde que las sesiones escriben cosas hacia y desde el disco, y cuanto más datos que usted está escribiendo, más tiempo se tarda en leer hacia atrás ...

3

Debido a que su aplicación es una aplicación Rails, sugeriría cualquiera:

  1. Usando la capacidad de sus clientes para almacenar en caché guardando en caché las tarjetas en javascript. (que había necesidad de una aplicación bastante AJAXy a hacerlo, consulte la última RailsCast para algunos puntos interesantes sobre el almacenamiento en caché de la página Javascript)
  2. Utilice uno de los muchos otros del lado del servidor opciones de caché carriles-compatibles (es decir MemCached) a almacenar estos datos en caché.
3

Un problema mucho más insidioso que encontrará al almacenar objetos directamente en la sesión es cuando está utilizando CookieStore (el valor predeterminado en Rails 2+ creo). Es muy fácil obtener errores de CookieOverflow que son muy difíciles de recuperar.

Cuestiones relacionadas