2011-02-11 14 views
7

Recibo un error con mis rutas cuando intento anular to_param en mi modelo de usuario para usar la dirección de correo electrónico como id. Parece que intenta hacer coincidir el objeto completo para el id cuando intenta hacer coincidir la ruta. ¿Alguien puede ayudarme a descubrir lo que me estoy perdiendo?Rails 3.0: error con las rutas al anular to_param en el modelo

Aquí está el error:

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

Así es como he establecido el código.

modelos/user.rb:

attr_accessible :email  

def to_param 
    email 
end 

controladores/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 

Y aquí está la salida de rutas de rake:

 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"} 
+0

muestran que enlace, lo que lleva a este error, por favor.Todo su código es correcto, entonces el error está en su enlace – fl00r

+0

El problema está en mostrar, editar, actualizar y destruir rutas. Por lo tanto, intente navegar a la ruta en el navegador (/users/[email protected], o llame a link_to en la vista, como <% = link_to "Show", usuario%>, o <% = link_to "Edit" , edit_user_path (usuario)%> – Bee

Respuesta

5

El problema es que el correo electrónico agrega un '.' (punto) en la url, y eso confunde los rieles, porque trata de encontrar un formato "com" (si el correo electrónico termina en .com)

He agregado este código a una de mis aplicaciones (tengo personas en lugar de Usuarios) y funciona correctamente, por lo que el truco es reemplazar el punto con algo más. Elegí reemplazarlo por '@', ya que otros símbolos, como - o +, son válidos en las direcciones de correo electrónico.

archivo person.rb

def to_param 
    email.sub ".", "@" 
end 

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

archivo people_controller.rb

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

Hay algunos más consejos acerca de cómo funciona esto en http://jroller.com/obie/entry/seo_optimization_of_urls_in.

Gracias por la pregunta, estoy empezando con los rieles, así que esto realmente me está ayudando a entender cómo funciona :).

+0

Gracias, Augusto! La publicación del blog me ayudó a entender mejor la situación de to_param. Sin embargo, creo que hay algo más que sucede aquí ... en mi controlador estoy usando find_by_email para encontrar al usuario de el param, en lugar del User.find. Parece tener un problema solo con el uso del correo electrónico en la ruta. Agregué un campo 'name' al modelo del usuario solo para probarlo, y funciona bien para anular to_param con el : atributo de nombre, pero el correo electrónico sigue fallando, incluso si antepongo la identificación según su sugerencia. ¿Alguna idea de por qué el correo electrónico falla específicamente? – Bee

+0

Encontré el problema. Vuelva a verificar la respuesta – Augusto

+0

Ah sí, veo en el resultado del error cuando muestra los parámetros que está analizando la parte '.com' en este argumento de formato. ¡Necesita ayuda para resolver esto! – Bee

2

Puede incluir puntos '.' en su valor de retorno to_param si se especifica una expresión personalizada regular para el parámetro 'id' en su ruta, por ejemplo:

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

Ver http://edgeguides.rubyonrails.org/routing.html#specifying-constraints para más detalles.

0

Encontré problemas al enviar la dirección de correo electrónico a través de GET.

#this url will cause the following problem 
/resend-validation/[email protected] 
params[:email] = [email protected] 

# 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*')