Cómo crear URLs amigables en Ruby on Rails: hola slugs!

Por defecto, las rutas en Rails generan URLs utilizando los IDs de los registros de nuestra base de datos. Así, es común encontrar una URL como esta:

https://myblog.com/posts/10

Este formato de URL, donde se usa únicamente un número para identificar un recurso, tiene algunas desventajas:

  • es malo para el SEO (aka optimización para buscadores)
  • conlleva una mala usabilidad, porque dificulta la comprensión y no ayuda a recordar la dirección

Para mejorar esto, existe lo que se conoce como slug y aquí veremos lo fácil que es incorporarlos a nuestro sistema con Ruby on Rails.

Un slug se refiere a una parte legible de la URL de un sitio web, que identifica de manera única un recurso específico. Los slugs suelen utilizarse en blogs y sitios donde se crea contenido dinámicamente, para que los enlaces sean más legibles y más amigables para los motores de búsqueda, lo que termina impactando positivamente en el posicionamiento de nuestra web en los resultados de búsqueda.

Para este ejemplo, vamos a suponer que ya tenemos una tabla `posts` en nuestra base de datos que representa los posteos/artículos de nuestro blog.

1) Agregamos el atributo slug a nuestra tabla

Agregamos una migración para crear el campo Slug y la corremos.

> rails generate migration AddSlugToPosts slug:string
> rake db:migrate

2) Creando el slug

El proceso de generación puede variar según la lógica de tu proyecto así que lo dejamos a tu criterio. Por ejemplo, podría copiarse del título cada vez que se cree/edite un nuevo post, o podría ser que un responsable de marketing lo ingrese manualmente antes de publicarse. En cualquier caso, para este ejemplo damos por hecho que ya tenés un slug guardado en la base de datos.

💡 Si vas a copiar el slug desde un atributo existente, te sugerimos mirar el método .parameterize, ya que reemplaza los caracteres especiales por guiones, resultando en un formato amigable para los navegadores y las urls.

3) Reemplazamos el ID por el Slug para las búsquedas

Para esto, una opción podría ser reemplazar todos los lugares donde se haga una consulta por ID para que pase a usarse el slug como parámetro. Sin embargo, gracias a los helpers de Rails, alcanza con sobrescribir el método to_param :

#app/models/post.rb

class Post < ApplicationRecord
# ...
def to_param
return nil unless persisted?

[id, slug].join('-') #10-como-ganar-la-copa-del-mundo-como-messi
end
end

Ahora, una pregunta válida viendo ese código podría ser: ¿por qué mantenemos el id y no usamos directamente el slug?

Esto es así porque si el método to_param retornara directamente el slug, al visitar /posts/como-ganar-la-copa-como-messien params[:id]recibiríamos el string “como-ganar-la-copa-como-messi”. Eso condicionaría las búsquedas, porque afectaría la performance -que podríamos solucionar indexando dicho campo- y además nos tendríamos que asegurar de que no se repitiera.

En cambio, al concatenar el id y el slug, nos evitamos tener que indexar el slug y mantenemos las ventajas de usar el ID. Así, cada vez que visitemos /posts/10-como-ganar-la-copa-como-messi, en params[:id] recibiríamos “10-como-ganar-la-copa-como-messi” y podremos estar seguros de que las búsquedas serán sobre el identificador 10, puesto que el método find de ActiveRecord ya aplica un .to_i, como se muestra aquí.

Con esto cerramos este artículo para crear URLs más amigables. Dejame saber qué te pareció usando los aplausos o comentarios.