4

In my Rails app a user can create one registry and the url's is for example:

http://localhost:3000/registries/3

How can I make that url be for example:

http://localhost:3000/erinwalker

Thanks in advance.

Erin Walker
  • 739
  • 1
  • 11
  • 30
  • As a side note, [this](http://stackoverflow.com/questions/1252506/rails-slugs-in-url-using-record-title-instead-of-id) question has quite a bit of useful information if you're looking to implement this by yourself: – Zajn Jun 14 '12 at 19:39

2 Answers2

4

The simplest way of doing this is by creating a new route at the bottom of your routes.rb file:

match "/:username" => "registries#show"

It's important to put this at the bottom of your routes.rb file as this will match any route of the format "/whatever" that doesn't match the routes preceding it.

This will point to the show action of your registries controller. So within that action you can just do

@user = User.find_by_username params[:username]
@registry = @user.registry
Nick Colgan
  • 5,488
  • 25
  • 36
  • I understand the match "/:username" => "registries#show" to a degree (I'm using devise), but why change my controllers? They all ready work fine. I didn't realize controllers were so connected to routes? – Erin Walker Jun 14 '12 at 20:45
  • Well, when you use the normal route (`/registries/:id`), you're getting the Registry through its ID (`Registry.find params[:id]`). Since you don't want to have to pass its ID, you need to find it in relation to the user model, so you have to change your controller to reflect that. – Nick Colgan Jun 14 '12 at 21:09
  • Sorry man, I'm still a newbe - it now says: undefined method `find_by_username' for #. From your code though, how will Rails know what registry belongs to the user? – Erin Walker Jun 15 '12 at 06:01
  • Well from your question, I assumed `erinwalker` was a username you had assigned to a user. In my example, I made the assumption that this was stored in a `username` column in your users table. For your case, it might be something else. If the column name is `screenname`, you can use `find_by_screenname`. If it's `login` you can use `find_by_login`. Just tailor it to your specific situation. – Nick Colgan Jun 15 '12 at 06:15
  • Ok, its a name column in the Users table - so I thought the first part is the table and second column, that's why I said username. I also changed match "/:username" => "registries#show" to match "/:name" => "registries#show". Now though it says undefined method `registry' for nil:NilClass. How can that be? Thanks so much for all the help - learning allot. – Erin Walker Jun 15 '12 at 06:42
  • Hmm... Well it's probably not finding a user that matches. If you add a `!` to the end of your finder method (`find_by_name!` in your case?), it should raise a `ActiveRecord::RecordNotFound` exception. If you need more help, I'd advise you to join the #rubyonrails IRC channel on freenode.net. – Nick Colgan Jun 15 '12 at 07:11
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/12590/discussion-between-erin-walker-and-xnm) – Erin Walker Jun 15 '12 at 07:37
1

The friendly_id gem and other slugging gems is, IMO, the easiest approach.

(And here's a friendly_id railscast.)

That said, it's easy to create a route that accepts legal slug values and redirect or look it up yourself.

Dave Newton
  • 158,873
  • 26
  • 254
  • 302