starscream_disco_party
starscream_disco_party

Reputation: 2996

Make URL be title of post

Currently my URL's appear as www.website.com/entries/1, I'd like to make them appear as www.website.com/title-of-entry. I've been messing around with routes and have been able to get the entry title to display in the URL, but Rails is unable to find the entry without supplying an ID. If I send the ID along with the parameters, the URL appears as www.website.com/title-of-entry?=1. Is there anyway I can pass the ID without having it appear in the URL as a parameter? Thanks!

Upvotes: 0

Views: 180

Answers (2)

James
James

Reputation: 2293

Like most things, there's a gem for this.

FriendlyID.

Installation is easy and you'll be up and running in minutes. Give it a whirl.

Upvotes: 1

Wukerplank
Wukerplank

Reputation: 4176

Ususally you'll want to to save this part in the database title-of-entry (call the field slug or something`). Your model could look something like this:

class Entry < ActiveRecord::Base

  before_validation :set_slug

  def set_slug
    self.slug = self.title.parameterize
  end

  def to_param
    self.slug
  end

end

Now your generated routes look like this: /entries/title-of-entry

To find the corresponding entries you'll have to change your controller:

# instad of this
@entry = Entry.find(params[:id]

# use this
@entry = Entry.find_by_slug(params[:id])

Update

A few things to bear in mind:

  1. You'll have to make sure that slug is unique, otherwise Entry.find_by_slug(params[:id]) will always return the first entry with this slug it encounters.

  2. Entry.find_by_slug(params[:id]) will not raise a ActiveRecord::RecordNotFound exception, but instead just return nil. Consider using Entry.find_by_slug!(params[:id]).

  3. If you really want your routes to look like this /title-of-entry, you'll probably run into problems later on. The router might get you unexpected results if a entry slug looks the same as another controller's name.

Upvotes: 1

Related Questions