Mejorando algunos scopes de Rails

Muchas veces, para filtrar los resultados por una relación padre, he hecho o me encontrado scopes como el siguiente:

scope :for_user, -> (user) { where(user_id: user.id) }

Que me permite hacer cosas del estilo

MiModelo.for_user( User.first )

Pero tiene el inconveniente de que sólo funciona con un parámetro de tipo User (bueno, en realidad con un objeto que responda a #id). En multitud de ocasiones me he encontrado con un modelo que tiene una dependencia belongs_to sobre User, es decir, tiene un atributo user_id pero que no puedo usar directamente, porque el scope sólo acepta un objeto. Así, acabo haciendo cosas del estilo de

# membership.user carga el objeto user de BBDD sin necesidad
MiModelo.for_user(membership.user)

Sin embargo, Rails es lo suficientemente listo para discriminar qué parámetro se le pasa al where, y si no forzamos que el parámetro sea un objeto, ampliamos muchísmo la funcionalidad del scope:

scope :for_user, -> (user) { where(user_id: user) }

Simplemente quitando el .id ya podemos hacer las siguientes consultas:

MiModelo.for_user(User.first)         # Usa un objeto como parámetro
MiModelo.for_user(User.active)        # Usa una relación como parámetro
MiModelo.for_user(User.active.to_a)   # Usa un array de objetos como parámetro
MiModelo.for_user(membership.user_id) # Use un número como parámetro
MiModelo.for_user(Course.user_ids)    # Usa un array de números como parámetro
MiModelo.for_user(1..100])            # Usa un rango de números como parámetro

Actualizando un rails congelado bajo subversion

Últimamente estoy actualizando algunos proyectos que tienen rails congelado bajo el directorio vendor -que es lo habitual cuando tienes varios proyectos en una máquina y no quieres estar pendiente de actualizar la aplicación cada vez que rails se actualiza en la máquina-, y lo primero que estoy haciendo es actualizar la versión de rails.

A primera vista, la actualización parece algo trivial:

rake rails:freeze:gems
rake rails:update

Pero cuando tienes el proyecto bajo subversion, en seguida te das cuenta del error: la tarea de rake lo primero que hace es

rm -rf vendor/rails
mkdir -p vendor/rails

con lo que se ha cargado el directorio .svn con toda la información que subversion almacena allí. En cuanto intentas hacer algo con subversion, te encuentras con problemas:

$ svn st
~       rails
$ svn add rails/
svn: warning: 'rails' is already under version control
$ svn commit rails/
svn: '/home/frsantos/project/vendor/rails' is not a working copy
$ svn del rails/
svn: Directory 'rails/.svn' containing working copy admin area is missing

con lo que te toca volver a la versión anterior y volver a empezar:

rm -rv vendor/rails/
svn up vendor

Lo sencillo en este caso es hacer svn delete, svn commit y hacer el freeze de nuevo, pero con esto estamos introduciendo una versión en el repositorio que no es consistente. Para la gente, como yo, a los que les gusta hacer un commit atómico con todos los ficheros que se han modificado para una funcionalidad, he preparado un script de shell que actualiza el directorio rails con los cambios de la última versión rails.

[dm]1[/dm]

Además, tiene el extra añadido de que crea un changelist con todos los ficheros modificados en ese directorio, por lo que si usas un entorno gráfico como RubyMine, te saldrá automáticamente en la pestaña de Changes el changelist con el nombre apropiado con todos los ficheros modificados (si usas este entorno, un consejo: crea un changelist y márcalo como el changelist por defecto. Cuando acabe el proceso, todos los ficheros modificados que no se hayan marcado con un changelist en subversion irán automáticamente a ese sitio).

Jornadas de formación interna en ASPGems

Aprovechando que tengo un par de semanas de vacaciones entre mi anterior trabajo en Utende y el nuevo en ASPGems, ayer me acerqué a la sede de Madrid On Rails para asistir a una de las charlas de formación interna que hace ASPGems, en este caso,
Lecciones aprendidas desarrollando “webs un poco grandes” con Rails, impartida por Diego. La charla en sí estuvo bastante interesante, y siempre viene bien conocer los problemas de rendimiento que han tenido otros en sus webs para cuando te tengas que pelear con la misma situación. Claro que a algunas de las optimizaciones que afectaban a Rails no les saqué todo el jugo posible, porque mi conocimiento de Rails está todavía un poco verde, así que tendré que revisarme la presentación en unos meses, cuando me haya puesto las pilas.

Aparte de la charla, ese día tocaban varias reuniones de empresa, a las que me sumé para conocer el equipo con el que voy a trabajar en breve. A muchos de ellos ya los conocía de mis tiempos de Qarana e incluso de Utende (Javi y yo fuimos cofundadores, entre otros) por lo que sé cómo piensa Agustín y no me sorprendió demasiado su forma de trabajar o la transparencia de la empresa -de hecho, esas han sido algunas de las razones que hicieron que me cambiara de trabajo-. Pero lo que sí me ha sorprendido, y mucho, es lo online que han llegado a estar.

Acostumbrado a trabajar durante 5 años para la SGAE en sus oficinas, donde todo está alojado en sus servidores, es un soplo de aire fresco comprobar que en mi nueva empresa muchas cosas las hacen online, como por ejemplo el correo y los documentos en Gmail, el tracker en Pivotal Tracker, la participación interna con Yammer…, aparte, por supuesto, de usar Twitter, messengers, blog personales… Si ahora mismo, antes de conocer a fondo a ASPGems me pidieran que la definiera con una palabra, esa sería online