Hace un tiempo en un experimento estábamos construyendo un sitio web para hacer sitios web, la parte compleja de este sitio era que el usuario que creaba su página web quería poner formularios de registros a su antojo y no teníamos como saber cuantos datos y como iba a querer guardarlos. En particular las bases de datos SQL como MySQL y PostgreSQL sufren este problema, necesitas conocer la estructura de antemano para poder guardar datos, pero existe una solución y lo mejor de todo es que está incorporada nativamente dentro de Rails y Postgres y consiste en ocupar la extensión HStore.

Arreglos en PostgreSQL

Para un ejemplo básico vamos a crear un proyecto de Rails desde cero, vamos a crear un modelo FOO con el campo bar, eso si, es importante estar ocupando postgreSQL en lugar de sqlite

Antes de hacer la migración vamos a revisar el archivo de migración generado y modificarlo para especificar que vamos a guardar un arreglo y que por defecto es un arreglo vacío.

Ahora podemos correr las migraciones con

y podemos entrar al rails console para crear un objeto foo y guardar un arreglo.

ahora el arreglo bar se comparta como un arreglo común de ruby y podemos utilizarlo así:

Hashes en PostgreSQL

Para guardar un diccionario o hash dentro de PostgreSQL primero necesitamos activar la extensión hstore de postgres primero vamos a generar una migración para agregar la columna baz del tipo hstore al modelo de Foo

luego antes de correr la migración tenemos que entrar y modificarle, primero para activar la extensión hstore y luego pare decir que la columna baz ingrese por defecto un hash vacío.

luego corremos las migraciones.

y ahora podemos entrar a la consola de rails para probar los hashs

Rescatar datos de un hash es sencillo cuando se hace como es el caso anterior, pero que pasa si queremos hacer una consulta en base a uno de los valores dentro del hash, esto también es posible, por ejemplo si queremos rescatar todos los Foo cuyo key del hash tiene un valor especifico también podemos hacerlo.

Para eso voy a repetir el experimento anterior creando el modelo User, con dos campos, name y favs donde en favs vamos a guardar las cosas favoritas del usuario, las cuales no sabemos todavía cuales son (si, podríamos hacer una tabla para los favoritos y realizar una relación de muchos a muchos con la de usuarios, pero lo que queremos hacer ahora es probar el hstore) entonces creamos el modelo de usuarios desde el bash:

y luego abrir el archivo de la migración el cual debería estar así:

(no es necesario habilitar nuevamente el modo hstore, lo hicimos en la migración pasada y se hace sólo una vez) ahora entramos nuevamente a rails console y empezamos a crear los primeros usuarios para hacer las pruebas

y ahora procedemos a hacer las consultas: Para rescatar a los usuarios cuya banda favorita sea Britney Spears, debemos hacerlo así:

Para rescatar a los usuarios cuya película favorita sea Twilight con

Ahora ocupando hstore y los arrays de Postgres puedes guardar datos sin necesidad de tener una estructura previamente definida, no se aconseja ocuparlo para no modelar el sitio, pero esto es especialmente útil cuando no sabes de antemano que es lo que tendrás que guardar.

Share Button

Director de DesafíoLatam. Ingeniero Civil Informático de la Universidad Federico Santa María. Emprendedor lean, dedicado al desarrollo de una mejor web con ruby on rails. Fanático de los números y las métricas, la música y la fotografía.