2009-05-01 6 views
12

Me gustan todas las rutas predeterminadas generadas por Rail map.resources. Pero, hay casos en los que me gustaría usar un identificador no numérico en mis rutas. Por ejemplo, si tiene una ruta anidada constan de los usuarios y sus artículos, una ruta estándar podría ser escrita como tal:Cómo cambiar el nombre del identificador predeterminado param "id" en el mapa de Rails()?

map.resources :users, :has_many => [:articles] # => e.g. '/users/:id/articles/:id' 

Sin embargo, hay muchas ventajas/razones para no utilizar el identificador numérico predeterminado generado por los rieles. ¿Hay alguna manera de reemplazar el parámetro default: id a otro identificador canónico de mi elección sin que se generen rutas personalizadas para cada acción estándar? Decir si quiero una ruta en el siguiente formato:

'/users/:login/articles/:id' 

Es este tipo de rutas alcanzable usando map.resources?

+0

p.s. Lo pregunto principalmente porque el sistema de enrutamiento de Merb tiene esta capacidad. – newtonapple

Respuesta

13

A partir de Rails 2.3, no es posible cambiar el nombre del parámetro y seguir utilizando el enrutamiento automático que proporciona #resources.

Como solución alternativa, puede asignar articles con un :path_prefix y :name_prefix:

map.resources :articles, :path_prefix => "https://stackoverflow.com/users/:login", 
         :name_prefix => "user_" 

El :path_prefix afecta la URL y el :name_prefix afecta a las rutas con nombre generados, por lo que va a terminar con estas rutas:

user_articles GET /users/:login/articles(.:format)   {:controller=>"articles", :action=>"index"} 
        POST /users/:login/articles(.:format)   {:controller=>"articles", :action=>"create"} 
new_user_article GET /users/:login/articles/new(.:format)  {:controller=>"articles", :action=>"new"} 
edit_user_article GET /users/:login/articles/:id/edit(.:format) {:controller=>"articles", :action=>"edit"} 
    user_article GET /users/:login/articles/:id(.:format)  {:controller=>"articles", :action=>"show"} 
        PUT /users/:login/articles/:id(.:format)  {:controller=>"articles", :action=>"update"} 
        DELETE /users/:login/articles/:id(.:format)  {:controller=>"articles", :action=>"destroy"} 

Como regla empírica general, sin embargo, me quedo con la convención por defecto rieles de :user_id, con el enrutamiento informados en su pregunta. En general, se entiende que :id y :user_id no implican necesariamente "identificador numérico": implican "identificador de recursos", cualquiera que sea. Y al seguir la convención predeterminada, su código será más fácil de entender para cualquier persona que haya utilizado rutas de recursos en Rails.

Para usar un identificador no numérico para un recurso, simplemente redefina #to_param en su modelo. Luego, asegúrese de usar un buscador en su controlador que encontrará por este identificador (en lugar de la identificación numérica), como User#find_by_login!.

+0

+1: una respuesta muy bien escrita. –

11

Puede cambiar el valor predeterminado de usar el ID en las URL anulando to_param en su modelo. p.ej.

class User < ActiveRecord::Base 
    def to_param 
    login 
    end 
end 

user_articles_path(@user) => "https://stackoverflow.com/users/:login/articles" 

El único otro cambio que deberá realizar es encontrar usuarios mediante el inicio de sesión en lugar de con una ID en los controladores.

+0

to_param intenta la generación de rutas. Pero al reconocerlo, todavía lo pasa como: user_id. ¿Hay alguna razón para cambiarle el nombre a: iniciar sesión? – newtonapple

+0

Es una respuesta bien escrita a una pregunta diferente:/La pregunta aquí es sobre el enrutador y cómo cambiar el nombre del parámetro de ruta ': id'. – Matchu

Cuestiones relacionadas