Gebruiksvriendelijke URL's met to_param

Het is al een tijdje een must geworden om zo veel mogelijk “user friendly” of “pretty” url’s te gebruiken in webapplicaties. Bijvoorbeeld website.be/artikels/artikel+titel, in plaats van website.be/artikels/toon.php?id=12 (12 is hier het unieke id van het artikel). Zo kunnen bezoekers aan de hand van de url makkelijk herkennen waar zij zich bevinden in de website, en ook zoekmachines zouden waarde geven aan keywords in de URL.

Dit kan echter problemen met zich meebrengen. “Oude” URL’s gebruikten primary keys om een item te identificeren, bijvoorbeeld /artikels/12. Dit is telkens een uniek getal dat automatisch aan elk artikel wordt gegeven. Zodanig is het onmogelijk dat 2 artikels dezelfde id hebben, en blijft de id van een record onveranderd. Wanneer men echter werkt met de “nieuwe” url’s zoals /artikels/mijn-artikel-over-rails, heeft men deze zekerheid niet meer. Wat bijvoorbeeld als 2 artikels de zelfde titel hebben? Of, wat als iemand de titel van een artikel veranderd? Dit zou ervoor zorgen dat externe links (bookmarks, links op andere sites, RSS feeds, ..) ineens ongeldig worden, met een foutmelding als gevolg.

De gulden middenweg

Dus, we houden niet van lelijke, nietszeggende URL’s, maar we willen natuurlijk wel dat alle URL’s werken en blijven werken. Dit wil zeggen dat we in de URL zowel een unieke id, als bv. de titel van het artikel of de naam van het product moeten plaatsen. Volgens mij is dit de mooiste oplossing: /artikels/12-mijn-artikel-over-rails. Nu mag ik de titel veranderen zo vaak ik maar wil, of in de browser bijvoorbeeld /artikels/12-iets-helemaal-anders-dan-de-echte-titel opvragen, het artikel zal nog altijd gevonden worden.

Om dit soort URL’s te genereren, maak je gebruik van de to_param method. Wanneer je bv. een url genereert met :id => @article, wordt eigenlijk de to_param methode in plaats van het id zelf opgeropen. Dus zullen we de to_param methode overschrijven in onze model:

...
def to_param
"#{id}-#{titel}"
end
...

Wanneer je nu een article_url(@article) maakt, zal dit /artikels/12-mijn-artikel genereren ipv. /artikels/12.

Oude links intact houden

Ik was zelf ook schuldig aan het mooi maken van url’s, zonder aan de gevolgen te denken. Ik heb dit dan ook aangepast, maar wou er voor zorgen dat “oude” links nog steeds zouden werken.

Daarvoor heb ik de candidate keys-plugin gebruikt, gekregen van tpope op #rubyonrails. Dit zorgt ervoor dat je een alternatieve kolom kunt opgeven wanneer op id gezocht wordt. Bijvoorbeeld; in mijn Article model plaatste ik volgende lijn:

  on_candidate_keys :find_by_titel

Dit zorgt er voor dat wanneer rails de opgegeven id niet terug vindt, hij dit zal gaan vergelijken met de titels, om alsnog het juiste artikel te vinden. Zowel /artikels/artikel-titel als /artikels/12-artikel-titel zijn nu dus geldige URL’s. Eindresultaat: de site gebruikt nu betere URL’s, maar alle oude URL’s blijven werken.

Reacties

Reageer als eerste!

Geef je mening… don't be shy

  • http://

Feed the primates

Wij hebben grote honger naar nieuwe projecten. Ook voor uw project leggen wij de lat heel hoog. Samenwerken? Stuur een berichtje. Of bel 09 395 02 51.

Een idee voor een nieuw project? We zijn benieuwd