2009-05-01 7 views
12

Mi piacciono tutti i percorsi predefiniti generati da Rail map.resources. Ma, ci sono casi in cui mi piacerebbe utilizzare un identificatore non numerico nei miei percorsi. Ad esempio, se hanno un percorso nidificato consistono degli utenti e dei loro articoli, un percorso standard potrebbe essere scritto come tale:Come rinominare l'identificatore di default param "id" in Rails 'map.resources()?

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

Tuttavia, ci sono molti vantaggi/motivi per non utilizzare l'identificatore numerico di default generato da Rails. C'è un modo per sostituire i parametri di default: id ad un altro identificatore canonico di mia scelta senza che ciò comporti la scrittura di percorsi personalizzati per ogni azione standard? Dire se voglio un percorso nel seguente formato:

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

è questo tipo di percorsi realizzabili utilizzando map.resources?

+0

p.s. Lo chiedo principalmente perché il sistema di routing di Merb ha questa capacità. – newtonapple

risposta

13

A partire da Rails 2.3, non è possibile modificare il nome del parametro e utilizzare ancora il routing automatico fornito da #resources.

Per risolvere il problema, è possibile mappare articles con un :path_prefix e :name_prefix:

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

Il :path_prefix colpisce l'URL, e l':name_prefix colpisce i percorsi denominati generati, così si ritroverà con questi percorsi:

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

Come regola empirica generale, però, mi piacerebbe restare con la convenzione di default Rails di :user_id, con l'instradamento avete inviato nella sua interrogazione. È generalmente inteso che :id e :user_id non implicano necessariamente "identificativo numerico" - implicano "identificatore di risorsa", qualunque esso sia. E attenendosi alla convenzione di default, il tuo codice sarà più facile da capire per chiunque abbia utilizzato le rotte delle risorse in Rails.

Per utilizzare un identificatore non numerico per una risorsa, è sufficiente ridefinire #to_param nel modello. Quindi, assicurati di utilizzare un finder nel controller che troverà questo identificatore (anziché l'ID numerico), ad esempio User#find_by_login!.

+0

+1: una risposta molto ben scritta. –

11

È possibile modificare l'impostazione predefinita dell'utilizzo dell'ID negli URL sovrascrivendo to_param nel modello. per esempio.

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

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

L'unico altro cambiamento è necessario fare è quello di trovare utenti login piuttosto che ID nel vostro controller.

+0

to_param tenta di generare percorsi. Ma al momento del riconoscimento, lo passa ancora come: user_id. È lì per rinominarlo in: login? – newtonapple

+0

È una risposta ben scritta a una domanda diversa:/La domanda qui riguarda il router e come rinominare il parametro di percorso ': id'. – Matchu

Problemi correlati