sisè / segona

Soy Víctor Rodríguez, programador web freelance con más de 10 años de experiencia

#CatalanReferendum

La semana pasada pasó con una mezcla de emociones y nervios. Eran los últimos días de septiembre y se acercaba el día del referéndum en Catalunya. No sabía si sería posible votar o no. El viernes, llegó una notificación del colegio donde estudia mi hijo, que es también mi colegio electoral, diciendo que cerraba a las 17h. Y nada más. Ya está? Así de fácil nos teníamos que rendir?

Pero llegó la noche del sábado. Yo seguía, como muchos, una aplicación que decía el estado de cada colegio electoral. Y vi que estaba abierto, con suficiente gente dentro. De repente ilusión y alegría.

El domingo me levanto antes de las 5. Habían pedido que la gente se concentrara delante de los colegios a proteger la llegada de las urnas. Proteger urnas! En el siglo XXI! Qué huevos! Cuando llegué ya había más de cien personas. Más ilusión y más alegría.

Recuerdo las personas que tenía al lado. la señora que se levantó a las cuatro para hacer café y repartirlo durante la espera. La lluvia, yo sin paraguas. La llegada de los mossos y como hicimos piña delante de la puerta. La llegada de dos chicas acreditadas, como se hizo el silencio, y como entraron en el colegio ocupado. La entrada de las urnas, que sí las tenían esas dos chicas. Más emoción y más alegría a cada momento. Y la apertura del colegio. Todo iba bien.

Al poco rato empiezan a llegar noticias y vídeos sobre las cargas que se estaban llevando a cabo para requisar las urnas. Casi no lo podía creer, porras, patadas, empujones, sangre, solo por hacer piña delante de los colegios. Y de ahí no se iba nadie, por más miedo que pudiéramos tener.

Así pasamos la mañana. Entre hacer cola para votar y esperando que llegaran los antidisturbios de la nacional o la guardia civil. Simplemente a repartir otra ración de porras.

De la misma forma pasó la tarde. Aunque ya había votado, había que seguir protegiendo las urnas y se pudieran contar los votos. Por suerte nuestro colegio no fue ‘visitado’.

Reconozco que una cosa sí consiguieron las porras. La emoción y la alegría se alternaba con la tristeza que aún siento. Ver sangrar a gente en otros colegios, y que quizás simplemente por azar a mi no me tocó. Más tarde ves como se justifican las agresiones, se niegan los heridos y se culpa a las víctimas. Es lo que más me duele y lo que peor llevo desde el domingo.

Simplemente no entiendo el estilo ‘la maté porque era mía’ que se está utilizando para evitar la independencia de Catalunya. Qué sentido tiene? A quién esperan convencer de esa manera? Para rematar la jugada, sale uno por la tele y echa más leña al fuego.

No se si se declarará la independencia. No se si será efectiva. No se si se sentarán a una mesa a negociar una salida. Lo que sí se es que no quiero más violencia, ni más justificación de ella, ni más mentiras. Y que si estos son los motivos que nos da el estado para querer quedarnos, más vale que salgamos rápido.

Render la última página vista en Rails

En Rails existe una manera muy sencilla de redireccionar a la última acción visitada por el usuario de nuestra aplicación. Es tan sencillo como llamar a esta función dentro de cualquier acción:

redirect_back(fallback_location, **args)

Opcionalmente se le puede pasar el parámetro fallback_location (con valor a una url o path por defecto) para asegurarnos que siempre llegará a algún sitio. Imagina que no ha habido ninguna petición anterior a esta llamada… 404?

Bueno, esto es a partir de la versión 5 de Rails, para versiones anteriores sería:

redirect_to :back

Pero no pasa lo mismo si lo que queremos es simplemente renderizar la última página vista.

Os pongo un ejemplo: tenemos un modelo que se puede editar/actualizar desde 2 páginas distintas en nuestra aplicación, pero como lo que estamos haciendo es actualizar los datos del modelo siempre acabamos llamando a la misma acción ‘update’ del controller del modelo. Algo así para el modelo User

def update
  @user = User.find(params[:id])
  if @user.update user_params
    redirect_to @user, notice: 'Usuario actualizado de manera correcta.'
  else
    render :edit
  end
end

Si las validaciones fallan a la hora de actualizar los datos, es habitual renderizar la pantalla anterior y mostrar los errores que se han producido. La clave es esta línea:

render :edit

El problema con esto es que siempre nos llevará a la misma pantalla, a la de edición, y a lo mejor queremos que la pantalla que vea nuestro usuario sea la de la vista de otro modelo (donde hemos editado los datos).

Bueno, pues aquí viene nuestro amigo referrer a la ayuda! En el objeto ActionDispatch::Request contiene la url previa visitada. Podemos acceder a dicha url mediante el header ‘Referer’ o directamente por el método request.referrer. Con esta información podemos traducir la url por un controlador y una acción gracias al router de la aplicación. La llamada sería la siguiente:

# con request.referrer = 'http://localhost:3000/user/1'
Rails.application.routes.recognize_path(request.referrer)
# Devolería: { :controller => 'users', :action => 'show', :id => '1' }

De esta manera, podemos acceder al action y llamar a render sin más en nuestro controller:

prev = Rails.application.routes.recognize_path(request.referrer) 
render prev[:action].to_sym

Si lo queremos hacer extensible a toda nuestra aplicación podemos crear el siguiente método dentro del ApplicationController:

def render_back(fallback)
  if request.referrer
    prev = Rails.application.routes.recognize_path(request.referrer)
    render prev[:action].to_sym
  else
    render fallback
  end
end

Y llamarlo siempre que necesitemos así:

render_back(fallback: :edit)

Ale, eso es todo. Bueno, un problema que veo en esta implementación es que no tenemos en cuenta el controller, por lo que sólo funciona de manera correcta siempre y cuando la edición/actualización del modelo sea desde dos acciones del mismo controller.

:P

Lanzar una Rails Task dentro de una migración

Para uno de los proyecto en los que estoy trabajando he creado una migración y una task para migrar unos datos. En concreto he usado, no se si llamarle pattern, counter_cache en una asociación entre modelos para evitar el problema de N+1 queries. Hasta ahí todo normal.

Lo curioso es que a la hora de publicar a producción la nueva versión he encontrado una manera de lanzar la task dentro de la migración. Así con una simple llamada de capistrano se ejecuta todo y no tengo que acceder al server a ejecutar la task manualmente. Os pongo el ejemplo:

class AddCommentsCountToArticle < ActiveRecord::Migration[5.0]
  def change
    add_column :articles, :comments_count, :integer, default: 0

    reversible do |dir|
      dir.up do
        Rake::Task['model:reset_counters'].invoke
      end
    end
  end
end

La clave está en llamar (invocar) la task dentro de este código:

reversible do |dir|
  dir.up do
    Rake::Task['namespace:taskname'].invoke
  end
end

Donde namespace es le namespace de la task y taskname el nombre que le hayas dado a tu task. Así de fácil.

:P

Generar helpers con Laravel 5

Estoy enfrascado en un proyecto en el que uso el framework de PHP Laravel 5.3. Y bueno, en un alarde de mantener limpio el código (seguir los principios KISS y DRY por ahí en medio) se me ocurrió crear un helper para visualizar números con formato en euros, algo así como number_to_currency de Ruby on Rails.

Y aquí empezaron mis dudas, ¿existe ya?, ¿cómo se llamará? Empecé a buscar pero no encontré nada en los helpers del propio framework. Así que vamos a crearlo de cero.

Buscando por Google encontré la solución, bastante sencilla además. Debes seguir los siguientes pasos:

1. Crea tu fichero helpers.php en app/Http/helpers.php por ejemplo. Ya que se va a utilizar para visualizar datos me parece un buen lugar para colocar el fichero.

2. Añade tu función helper dentro del fichero. Esta es la mía:

<?php

function currency($price) {
    return number_format($price, 2, ',', '.') . ' €';
}

3. Registra el fichero helpers en el fichero composer.json:

"autoload": {
    ...,
    "files": [
        "app/Http/helpers.php"
    ]

4. Haz que la aplicación se entere con este comando:

composer dump-autoload

Y ala, a utilizar el helper!

Comenzar de nuevo

Voy de camino a Madrid. Más concreto, a la Conferencia Rails que se celebra este fin de semana. Y me siento como si volviera a empezar como freelance. 

Hacía cuatro meses que me levantaba cada mañana para ir al mismo sitio. Una oficina de la Diagonal, abrir un pc, conectarme a dos VPNs (sí, a falta de una, dos), y pasar la jornada laboral en el mismo proyecto. Pero eso se acabó ayer. 

Lo mejor de este tiempo ha sido sin duda la gente que he encontrado. Embutido en un bocadillo de Guillermos, qué grandes sois bros., con Lucia, Clara, Sandy y Toño por un lado, y la frontera ES-PT ;) por otro he pasado buenos momentos. Roberto, Noemi, Oriol, Laura y Toni. Bueno, a todos los que han ayudado cuando ha hecho falta. Un placer haberos conocido.