Per fare questo basta sovrascrivere il metodo to_param di ActiveRecord, questo normalmente resituisce la primary key della risorsa.
class Post < ActiveRecord::Base def to_param "#{id}-#{title}" end end
In questo caso suppongo di avere una risorsa Post che abbia un campo title che rappresenta il titolo del post.
E' sempre meglio togliere da title tutti i caratteri che non siano numeri o lettere e magari mettere tutto in minuscolo, questo farà al caso nostro
class Post < ActiveRecord::Base def to_param "#{id}-#{title.downcase.gsub(/[^[:alnum:]]/,'-')}".gsub(/-{2,}/,'-') end end
Inseriamo nella view il link per la visualizzazione dei nostri posts
<% @posts.each do |post| %> <%= link_to "Show", post %> <% end %>
E questo magicamente sarà posts/1-nome-del-mio-post.
Una domanda è d'obbliglo, sarà ancora possibile recuperare un post attraverso la sintassi
Post.find(1)
certo che si e la stessa cosa si potrà fare con
Post.find("1-nome-del-mio-post")
infatti rails è abbastanza furbo da chiamare il metodo to_i quando il campo rappresentato nel database è di tipo :integer come nel caso della mia primary key, rails inoltre cerca i valori interi contigui all'interno della stringa passata a find in modo da ricavarne l'id.
Ora supponiamo di avere un controller chiamato manage che visualizza tutti i post, al suo interno avremo un'azione show_post che recupera tutti i post e li rende disponibili nella view.
class PostsController < ApplicationController def index @posts = Post.all end endIn questo caso gli URLs non saranno ottimizzati, perchè per chiamare la suddetta azione dobbiamo visualizzare i link così
<% @posts.each do |post| %> <%= link_to "Show", :controller=> :menage, :action => 'show_post', :id => post.id %> <% end %>
e non facciamo riferimento al modello Post, che fare?
Possiamo aggiungere una nuova root in modo da farsì che gli URLs vengano automaticamente ottimizzati.
map.spins 'manage/:title/:id', :controller => 'manage', :action => 'show_post', :id => ':id'
in questo modo tutte le richieste del tipo manage/:title/:id verranno girate manage/show_post/:id, creiamo in manage_helper questo helper che ci aiuterà a richiamare la corretta root.
def link_showpost_seo(link_title,post, title_a ,css_class="") link_to link_title, spins_url(:title => post.title.gsub(/[^[:alnum:]]/,'-').gsub(/-{2,}/,'-'), :id => post.id), :title => title_a, :class => css_class end
In questo modo nella view sarà sufficiente richiamare l'helper
<%= link_showpost_seo(post.title, post, "Leggi #{post.title}") %>
Così otteniamo il medesimo risultato.
CONCLUSIONI
E' importante ottimizzare gli URLs del nostro sito sia si tratti di e-commerce o di un semplice blog, la parte di riguardante il SEO è composta da una multitudine di elementi tali che è importante prestare attenzione anche alle piccole cose come questa, ovviamente rails ci dà una mano a farlo in piena filosofia REST way.