Jakub Lédl
Jakub Lédl

Reputation: 1805

Rails routing - custom routes for Resources

I'm building currently one Rails app and I'd like to stick to all those fancy things like REST and Resources, but I'd like to customise my routes a little. I want my GET route to be little more verbose - the app I'm creating is a simple blog, so instead of GET /posts/1 I'd prefer something like GET /posts/1-my-first-post.

Any ideas how to do this? Didn't find anything on the web.

Upvotes: 6

Views: 2737

Answers (5)

Paul Groves
Paul Groves

Reputation: 4051

Alternatively...

Add a method like this to application_helper.rb

def permalink(post)
  "#{post_path(post)}-#{post.slug}"
end

Then use the following in your views (using permalink(@post) instead of post_path)

<%= link_to @post.title, permalink(@post) %>

Upvotes: 0

hurikhan77
hurikhan77

Reputation: 5931

You could find the friendly_id plugin useful as it will also handle redirections if you rename your slugs (thus seo friendly), handles name collisions and seamlessly integrates with the find method so you don't need to touch your controller methods (except for the redirection thingy).

Upvotes: 2

Paweł Gościcki
Paweł Gościcki

Reputation: 9594

Alternatively...

Add a method like this to post.rb

def path
  "/posts/#{id}-#{slug}"
end

Then use the following in your views:

Upvotes: 0

Tomas Markauskas
Tomas Markauskas

Reputation: 11596

Define a to_param method in your Model and all the url helpers will youse what you return with that method, e.g.:

class Post < ActiveRecord::Base
  der to_param
    slug
  end
end

You will also need to adapt your controllers for that. Replace:

Post.find(params[:id])

with:

Post.find_by_slug(params[:id])

Also note that the find method raises ActiveRecord::RecordNotFound exception when the record can't be found while using the find_by_* method no Exceptions will be raised so you need to check that manually.

Upvotes: 4

Paweł Gościcki
Paweł Gościcki

Reputation: 9594

Routes:

map.resources :posts

Model:

class Post < ActiveRecord::Base
  def to_param
    "#{id.to_s}-#{slug}"
  end
end

Should do the trick.

Btw: http://railscasts.com/episodes/63-model-name-in-url

Upvotes: 16

Related Questions