I’m getting an error with my routes when I try to override to_param in my user model to use the email address as the id. It appears to be trying to match the entire object for the id when it tries to match the route. Can anyone help me figure out what I’m missing?
Here’s the error:
No route matches {:controller=>"users", :action=>"show", :id=>#<User id: 1, email: ....>}
Here’s how I’ve set up the code.
models/user.rb:
attr_accessible :email
def to_param
email
end
controllers/users_controller.rb:
before_filter :get_user, :only=>[:show,:update,:edit,:destroy]
...
def get_user
@user = User.find_by_email params[:id]
end
config/routes.rb
resources :users
And here’s the output from rake routes:
user GET /users(.:format) {:controller=>"users", :action=>"index"}
POST /users(.:format) {:controller=>"users", :action=>"create"}
new_user GET /users/new(.:format) {:controller=>"users", :action=>"new"}
edit_user GET /users/:id/edit(.:format) {:controller=>"users", :action=>"edit"}
user GET /users/:id(.:format) {:controller=>"users", :action=>"show"}
PUT /users/:id(.:format) {:controller=>"users", :action=>"update"}
DELETE /users/:id(.:format) {:controller=>"users", :action=>"destroy"}
The problem is that the email adds a ‘.’ (dot) in the url, and that confuses rails, because it tries to find a “com” format (if the email ends in .com)
I’ve added this code to one of my apps (I have People instead of Users) and it works properly, so the trick is to replace the dot with something else. I chose to replace it with an ‘@’ as other symbols such as – or + are valid in email addresses.
file person.rb
file people_controller.rb
There are some more hints about how this works in http://jroller.com/obie/entry/seo_optimization_of_urls_in.
Thanks for the question, I’m just starting with rails, so this is really helping me to understand how it works :).