Rails 3.0: error with routes when overriding to_param in model

I get an error with my routes when I try to override to_param in my user model to use the email address as an identifier. It seems to be trying to map the entire object for the identifier when it tries to map the route. Can someone help me figure out what I am missing?

Here's the error:

No route matches {:controller=>"users", :action=>"show", :id=>#<User id: 1, email: ....>} 

This is how I set up the code.

/ user.rb models:

 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 is the conclusion from the 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"} 
+7
source share
4 answers

The problem is that the letter adds '.' (period) in the url, and this confuses the rails because it tries to find the format "com" (if the message ends in .com)

I added this code to one of my applications (I have people instead of users) and it works correctly, so the trick is to replace the point with something else. I decided to replace it with "@", as other characters, such as - or +, are valid in email addresses.

person.rb file

 def to_param email.sub ".", "@" end def self.param_to_email(param) segments = param.split '@' host = segments[1..-1].join('.') segments[0] + '@' + host end 

file people_controller.rb

 def get_person email = Person.param_to_email params[:id] @person = Person.find_by_email email end 

There are some tips on how this works at http://jroller.com/obie/entry/seo_optimization_of_urls_in .

Thanks for the question, I'm just starting with the rails, so it really helps me understand how this works :).

+5
source

You can include dots. in the to_param return value if you specify a custom regular expression for the id parameter on your route, for example:

 match '/images/:id', :via => :get, :constraints => { :id => /[^\/]+/ }, :format => false, :to => 'images#show', :as => :image 

See http://edgeguides.rubyonrails.org/routing.html#specifying-constraints for more details.

+2
source

I'm having trouble sending my email address via GET.

 #this url will cause the following problem /resend-validation/ abcd@abcd.com params[:email] = abcd@abcd # I had to encode the email: <%= link_to('Resend Code', resend_activation_path(:email => user.email.unpack('H*'))) %> # than decode it in controller: email = params[:email].split.pack('H*') 
0
source

To avoid transmission problems '.' (dot) '.' (dot) via a URL that you can add to your route definition:

 resources :users, :id => /.*/ 

Credits: stack overflow

0
source

All Articles