2010-04-14 13 views
20

Sto leggendo queste due pagineCome aggiungere una rotta REST personalizzata a un'app Rails?

  1. resources
  2. Adding more RESTful actions

La pagina di Rails Guide mostra

map.resources :photos, :new => { :upload => :post } 

e il suo corrispondente URL

/photos/upload 

Questo sembra meraviglioso.


mie routes.rb mostra questo

map.resources :users, :new => { :signup => :get, :register => :post } 

Quando faccio: [~/my_app]$ rake routes

vedo le due nuove rotte aggiunti

signup_new_user GET /users/new/signup(.:format) 
register_new_user POST /users/new/register(.:format) 

Nota l'inclusione di /new! I non lo voglio. Voglio solo /users/signup e /users/register (come descritto nella Guida al percorso dei binari).

Qualsiasi aiuto?

risposta

61

Quando si espone un controller come una risorsa, sono aggiunti automaticamente seguenti azioni:

show 
index 
new 
create 
edit 
update 
destroy 

Queste azioni possono essere classificati in due gruppi: le azioni

  • :member

L'URL per l'azione membro ha l'id della risorsa di destinazione. E.g:

users/1/edit 
users/1 

si può pensare :member azione come un metodo di istanza su una classe. Si applica sempre a una risorsa esistente.

azioni membro predefinito: show, edit, update, destroy

  • :collection azioni

L'URL per l'azione :collection non contiene l'ID della risorsa di destinazione. Per esempio:

users/login 
users/register 

si può pensare :collection azione come un metodo statico su una classe.

azioni di recupero di default: index, new, create

nel tuo caso si bisogno di due nuove azioni per la registrazione. Queste azioni appartengono a: tipo di raccolta (poiché non hai l'ID dell'utente mentre invii queste azioni). Il percorso può essere la seguente:

map.resources :users, :collection => { :signup => :get, :register => :post } 

L'URL per le azioni sono i seguenti:

users/signup 
users/register 

Se si desidera rimuovere un'azione standard generato da Rails usa: tranne /: uniche opzioni:

map.resources :foo, :only => :show 

map.resources :foo, :except => [:destroy, :show] 

Modifica 1

solito t ricomporre l'azione confirmation come azione :member. In questo caso params[id] conterrà il codice di conferma.

configurazione Percorso:

map.resources :users, :member => { :confirm => :get} 

URL

/users/xab3454a/confirm 

confirm_user_path(:id => @user.confirmation_code) # returns the URL above 

controller

class UsersController < ApplicationController 
    def confirm 
    # assuming you have an attribute called `confirmation_code` in `users` table 
    # and you have added a uniq index on the column!! 
    if User.find_by_confirmation_code(params[id]) 
     # success 
    else 
     # error 
    end 
    end 
end 
+0

@KandadaBoggu, questa spiegazione sembra fantastica. Come follow-up per verificare la mia comprensione, dire che volevo inviare un link "conferma account" nell'e-mail di benvenuto dell'utente. Quel link contiene un hash di convalida di 8 caratteri. Vorrei aggiungere 'map.resources: users,: member => {: validate =>: get}'? Come viene inserito il parametro 'hash'? –

+0

Aggiornato la mia risposta, dai un'occhiata. –

+0

Cosa dice 'confirm_user_path' per usare' @ user.confirmation_code' al posto del carattere jolly ': id' invece di' @ user.foo' o '@ user.bar'? Dovrebbe essere 'confirm_user_path (: id => @ user.confirmation_code)'? –

1

L'opzione new consente di creare nuovi percorsi per la creazione di nuovi oggetti. Ecco perché sono preceduti da quel termine.

Quello che stai cercando è l'opzione :collection.

map.resources :users, :collection => { :signup => :get, :register => :post } 

Che creerà le /users/signup e /users/register URL.

+0

Ho avuto problemi a capire a cosa fosse destinata la raccolta. La rotta ** è ** per la creazione di nuovi oggetti; i visitatori che si registrano creano un nuovo oggetto 'Utente'. Quindi, perché non vorrei usare 'new'? Si tratta di un errore di battitura nella Guida alle guide? –

3

Se sto capendo bene la tua domanda, vuoi semplicemente rinominare gli url delle azioni new e create.

Questo sarebbe stato fatto in questo modo:

map.resources :users, :path_names => {:new => 'signup', :create => 'register'} 

Se davvero volete aggiungere nuove rotte con corrispondenti azioni di controllo, quindi Damiens risposta è la strada da percorrere.

+0

@ mikezter, ho sicuramente ancora bisogno delle rotte 'new' e' create'. Tuttavia, questo risponde alla domanda su * rinominare * percorsi che ho avuto in passato. Grazie :) –

12

Questo può essere preso come jus Un altro sintassi: qualcosa di buono da sapere.

Sintassi 1:

resources :users do 
    member do 
    get 'signup' 
    post 'register' 
    end 
end 

Rake uscita percorso includerà

signup_users GET /users/signup(.:format) {:action=>"signup", :controller=>"users"} 
register_users POST /users/register(.:format) {:action=>"register", :controller=>"use 

rs "}

Sintassi 2: Se si dispone di un solo insieme di rotte

resources :users do 
    get 'signup', :on => :collection 
end 
+0

Mi piace la sintassi 2, simpatica testata – Francois

Problemi correlati