Skip to content

Instantly share code, notes, and snippets.

@jamesu
Forked from Overbryd/document.rb
Created February 19, 2010 18:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jamesu/309046 to your computer and use it in GitHub Desktop.
Save jamesu/309046 to your computer and use it in GitHub Desktop.
class Document < ActiveRecord::Base
after_save :update_permalink
def to_param
permalink.blank? ? id.to_s : permalink
end
private
def update_permalink
if permalink.blank? && !(title.blank? || isbn.blank?)
update_attribute(:permalink, "#{id}-#{title} #{isbn}".parameterize)
end
end
end
# SPECS
# Note: I am using blueprint for my 'Document' model. (gem install machinist)
describe "permalink" do
before :each do
@document = Document.make :title => 'I want to be in the permalink', :isbn => '978-5-2054-6661-5'
@expected_permalink = "#{@document.id}-i-want-to-be-in-the-permalink-9785205466615"
end
it "should set a permalink" do
@document.permalink.should eql(@expected_permalink)
end
it "should not change indirectly" do
@document.update_attribute(:title, 'Oh I changed my mind')
@document.reload.permalink.should eql(@expected_permalink)
@document.update_attribute(:isbn, Faker::Isbn.isbn_13)
@document.reload.permalink.should eql(@expected_permalink)
end
it "should not set a permalink if one of the permalink components is blank" do
@document = Document.make_unsaved(:title => '')
@document.save(false)
@document.permalink.should eql(nil)
@document = Document.make_unsaved(:isbn => '')
@document.save(false)
@document.permalink.should eql(nil)
end
it "should use the permalink in params" do
@document.to_param.should eql(@expected_permalink)
end
it "should use the id in params if no permalink is set" do
@document.permalink = nil
@document.to_param.should eql(@document.id.to_s)
end
it "should fetch a document the conventional way" do
# Hint: Rails is converting the given id attribute to an integer. This works because '123-whatever'.to_i evaluates as 123.
Document.find(@expected_permalink).should eql(@document)
Document.find_by_id(@expected_permalink).should eql(@document)
end
end
F**K FRIENDLY ID. Why did I ever believe in you?
Yes, it was my very own fault to install this piece of s**t.
To all other people wondering if they should install a gem to take care of friendly ids. Note that I use the term 'permalink' in the meaning of a 'nice looking permalink' or 'Friendly Permalink'.
* It is a bad decision to go with a solution on steroids (or from texas) if you just need to accomplish one simple thing: Nice looking urls that don't break your existing code.
* Versioned permalinks? Way too nerdy plus bad idea at all. If you fail to create a useful permalink in the first place, you should not even start to create permalinks.
There are some hardcore 2 % edge cases often related to a legacy codebase. Anyways, projects with such issues scream for a rewrite.
* Get Real! Think about your business case. Acceptance tests have shown that friendly permalinks are a luxury problem. Do you _really_ need to solve a luxury problem?
* 99% of users just care about the usefulness of your application, not about good looking URI's. The kind of persons (sorted by stupidity) who care are:
* Managers who think that the SEO guy is more worth than the developer
* Overpayed SEO guys
* Plain old Nitpicks
* Managers that don't listen to their developers
* 'Friendly Permalinks' have one bad aspect: They should be permanent and should never change. It _will_ cost you a lot of resources (time, money) migrating permalinks from old to new! Therefore think twice as much before implementing such a luxury thing. Use the simplest most lasting solution (IDS MAYBE???)
Talk to me if you feel uncomfortable with my write up. @Overbryd
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment