There is just something nice about those cute URIs that we have all grown to love, I’m sure you’ve seen them around: http://pork.ham/lists/32-grocery-list. Guess what, these are fun and easy to implement, here’s how!
First we need a method that can convert a normal title or name into something safe for use in a URI, here’s my answer:
class ::String
# Returns a version of self that is safe for inclusion in a URI.
def urilize
strip.
gsub(' ', '-').
gsub(/[-]+/, '-').
gsub('&', 'and').
downcase.
scan(/[a-z0-9\-]*/).to_s
end
end
Users enter the darnedest data, so your urilize implementation will probably be tweaked over time. Anyways, the above String extension let’s us do stuff like:
'My Name Is Mud!'.urilize # => "my-name-is-mud"
'Awesome & Cool Stuff!!!'.urilize # => "awesome-and-cool-stuff"
Now we need a seamless way to get this functionality into our models so that they start throwing around all of these cool URIs for free. My answer to this is a sweet and simple mixin:
module Findable
def to_param
to_s.blank? ? id.to_s : "#{id}-#{to_s.urilize}"
end
end
In order for our mixin to work we need our ActiveRecord models to have an overloaded to_s method that returns the title or name of the object. This is good practice and you should be doing it in any model where it makes sense to do so.
Anyways we can use our mixin as follows:
class Ticket < ActiveRecord::Base
include Findable
...
def to_s
title
end
...
end
Now imagine we have the following ticket in our database:
id: 6
created_by: Captain Obvious
assigned_to: Developer Dude
title: Feature Improvements
body: This massive feature that you implemented in far too little time is imperfect!
Assuming resourceful routes for Tickets we can do something like:
ticket = Ticket.find(6)
ticket_path(ticket) # => "/tickets/6-feature-improvements"
Neat.
Recommend me on Working With Rails
View My LinkedIn Profile