¿Qué son las Friendly URL?

Una URL Amistosa o Friendly URL (en inglés), es una dirección que en lugar de tener números y cientos de símbolos raros contenga un titulo o un tag, o sea en lugar de:

http://www.desafiolatam.com/blog/20/

obtienes:

 http://www.desafiolatam.com/blog/articulo-genial-sobre-programacion/

¿Cuál es la ventaja de una friendly URL?

– Para los humanos es más fácil leer y entender en que página están y lo que están viendo, o sea es human friendly

– Los crawlers de google (u otros indexadores) utilizan el título de la página para determinar las palabras claves del sitio para calcular la relevancia. Tener una url friendly mejora el SEO del sitio, a esto se le denomina que el sitio sea SEO friendly URL

¿Cómo se crea una friendly url en Ruby on Rails

El concepto clave para poder crear friendly URL consiste en entender el concepto de Slug

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:


gt; rails new blog

Acceder a la carpeta «blog» desde el terminal:


gt; cd blog

gt; rails s

2. Creando el Scaffold: Post.


gt; rails g scaffold post title:string description:text

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


gt; rake db:migrate

Cambiando el archivo Routes.rb

busca donde dice:

# root 'welcome#index'

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

root 'posts#index'

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:



gt; rails g migration addSlugToPost slug:string

Ejecutamos en otra terminal:


gt; rake db:migrate

el resultado debe ser el siguiente:

schema de post con slug

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

4.1. Definiendo Callbacks.

 #callbacks
 after_create :update_slug
 before_update :assign_slug

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.

 #redefinimos el metodo to_param
 def to_param
     slug
 end

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.

#metodos privados.
private

def assign_slug
    self.slug = "#{ title.parameterize }"
end

def update_slug
    update_attributes slug: assign_slug
end

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. Último 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)

def set_post
  @post = Post.find(params[:id])
end

Reemplázalo por esto:

def set_post
  @post = Post.find_by_slug(params[:id])
end

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:

 resources :posts

cambia  por esto:

resources :posts, :path => ''

Ahora solo nos queda probar nuestra aplicación de Posts con url amistosas!

(repo en github)

KEEP CODING! 😀