Crear url friendly en Ruby on Rails en 5 pasos.

En este tutorial (repo en github) te explico como crear de manera simple una url friendly o url amigable a partir de un “slug” para tu aplicación en rails.

El concepto de Slug es un término que hace referencia al título de una noticia o artículo en el que se han sustituido los espacios en blanco por guiones y se han eliminado todos los caracteres que no sean letras o números.
Ahora que  sabemos que es el slug, vamos al paso a paso para generar slug automáticamente para nuestros posts.

Ejemplo:
título de la noticia: ¿Cómo crear un Slug en Rais?
Slug: como-crear-un-slug-en-rails

1. Creando el Proyecto Blog.

Abres una Terminal y escribes:

Acceder a la carpeta “blog” desde el terminal:

2. Creando el Scaffold: Post.

Antes de este paso revisa siempre tu migración!. Luego ejecutamos en el terminal:

Cambiando el archivo Routes.rb

busca donde dice:

Quita el signo # para descomentar y cámbialo por:

3. Agregando una nueva columna “slug” a la tabla posts.

Como no queremos que el campo “slug” aparezca por pantalla ni tampoco como strong parameter, generamos una nueva migración al modelo de post:

Ejecutamos en otra terminal:

el resultado debe ser el siguiente:

simple tutorial to create posts with friendly url in Rails

4. Modificando el Modelo de Post (app/models/post.rb)

4.1. Definiendo Callbacks.

el primer callback es “after_create” el cual tendrá asociado un método llamado “update_slug” el cual se llama  inmediatamente “después de crear” un nuevo post.

el segundo callback es “before_update” el cual se llama “antes de actualizar” cualquier atributo del modelo post.

4.2. Reemplazando el método to_param.

Lo que acabamos de hacer es un “override” del método  to_param en nuestro modelo post, con el objetivo de que post_path contruya una ruta usando la columna “slug” de un post en lugar de su id. esto lo usaremos más adelante en el controller posts_controller.rb

4.3. Creando Metodos privados para manejar el valor del slug.

El primer método “assign_slug” lo que hace es asignar un valor a slug, el cual será el “title” del post con un formato trabajado de manera que se reemplacen los caracteres especiales y se agreguen guiones entre espacios vacíos. este trabajo lo se lo dejaremos al método .parameterize.

Luego viene el siguiente método “update_slug”, el cual se gatilla con el callback “after_create” (que definimos al principio del modelo) es decir, inmediatamente después de crear un post, se actualizará el atributo “slug” con el valor que retorne el método assign_slug.

5. Ultimo paso: Modificando el posts_controller.rb

Ahora que agregamos lo necesario en el modelo, vamos a intervenir el controller, abre app/controllers/posts_controller.rb y revisa el metodo set_post (se ubica al final del archivo)

Reemplázalo por esto:

Hay un método que Rails nos provee que son los “find_by_algunAtributo” este tipo de métodos son convenientes para buscar registros a partir del valor de un atributo, estos métodos se denominan “dynamic finders” .

Observación: es importante que en el modelo esté el override de to_param bien definido para que params[:id] entienda que buscamos por columna slug y no por id.

y el Bonus track!

Podemos “ocultar” el controller de la url haciendo un truco muy sencillo en el archivo routes.rb de modo que:

http://www.example.com/posts/como-crear-un-slug-en-rails

se transforme a esto:

http://www.example.com/como-crear-un-slug-en-rails

Para ocultar el controller en la url tenemos que hacer lo siguiente, donde dice:

modificalo por esto:

Ahora solo nos queda probar nuestra aplicación de Posts:

Agrega un nuevo post:

Click en create post. Verás en la url que ahora sale el “slug” en lugar del id!

y si modificas el titulo del post, gracias a lo realizado en el Modelo de Post también se actualizará el Slug respectivo.

(repo en github)

KEEP CODING! 😀

Written by Daniela Gattoni

Software Engineering Student at USM, Santiago, Chile. Web Designer & programmer. #hack4good Santiago 1st place 2014 with #BringYourCup app.

Leave a Comment

Your email address will not be published. Required fields are marked *