www.github.com/Nielsomat/has_slug
./script/plugin install git://github.com/Nielsomat/has_slug.git or git submodule add git://github.com/Nielsomat/has_slug.git vendor/plugins/has_slug
has_slug provides an easy way to equip your models with “permalinks” like so:
class BlogPost < ActiveRecord::Base has_slug(:category, :title) end post = BlogPost.create(:category => “Time Travelling”, :title => “Yatta!”) # => #<BlogPost id: 1, category: “Time Travelling”, title: “Yatta!”> post.to_param # => “1-time-travelling-yatta”
That’s nice. But surely not revolutionary.
So let’s turn our attention to the controller which should of course be able to find the record identified by the above “permalink”. Turns out that Rails kinda does this by default by virtue of calling to_i on params when passing it to ActiveRecord. Easy enough..
But wait, there’s more!
Of course this automatic conversion means that your carefully worded “2-honey-you-look-great-in-that-dress” could also be accessed under “2-youre-way-too-fat-for-that-dress-honey”. Not so good. In fact, just anything matching /^2/ would lead to BlogPost.find(2). Besides upsetting your wife and/or mistress, this might obvisouly also annoy search engines which have a fetish for unique resource itentifiers (i.e. URIs).
But fear not for it has all been taken care of for you!
class BlogPostsController < ApplicationController rescue_from SlugMismatchError { |item| redirect_to(blog_post_url(item), :status => :moved_permanently) } def show check_slug!(@post = BlogPost.find(params), params) end end
And behold: GET /blog_posts/2-honey-you-look-great-in-that-dress
will render /blog_posts/show.hmtl.erb
while GET /blog_posts/2-youre-way-too-fat-for-that-dress-honey
will 302
to /blog_posts/2-why-i-love-my-wife
.
Even better though, the above example actually still works when written like this:
class BlogPostsController < ApplicationController def show check_slug!(@post = BlogPost.find(params)) end end
Because awesomely enough, the second parameter to check_slug! defaults to params and by default, all ApplicationController descendants are lovingly wired to rescue you from SlugMismatchErrors by redirecting to model_url(model).
So what are you waiting for? Just has_slug
your models and consider your application awesomified!
Copyright © 2008-2009 Niels Ganser, released under the MIT license. Even though this software is released “as is”, I accept full responsibility for any bone fractures that might directly result from using it. So in the case of such spontaneous fracturing, feel free contact my armada of lawyers to discuss your ridiculously high compensation claims.
Feel free to send pull requests for found bugs or feature suggestions via Github or just drop me a line via email (niels herimedia com).
Shout-out to Christoffer Sawicki & Henrik Nyh for creating Slugalizer, upon which this plugin was originally based (obsolete since Rails 2.2)!