2010-07-27 8 views
10

Ho due classi:Rails 3 has_one instradamento

class User < ActiveRecord::Base 
    :has_one :foo 
end 

class Foo < ActiveRecord::Base 
    :belongs_to :user 
end 

Il Foo è opzionale.

ho creato il seguente percorso:

resources :users do 
    resources :foo 
end 

che si traduce nei seguenti percorsi:

GET /users/:user_id/foo(.:format)    {:controller=>"foos", :action=>"index"} 
user_foos POST /users/:user_id/foo(.:format)    {:controller=>"foos", :action=>"create"} 
new_user_foo GET /users/:user_id/foo/new(.:format)   {:controller=>"foos", :action=>"new"} 
GET /users/:user_id/foo/:id(.:format)   {:controller=>"foos", :action=>"show"} 
PUT /users/:user_id/foo/:id(.:format)   {:controller=>"foos", :action=>"update"} 
user_foo DELETE /users/:user_id/foo/:id(.:format)   {:controller=>"foos", :action=>"destroy"} 
edit_user_foo GET /users/:user_id/foo/:id/edit(.:format)  {:controller=>"foos", :action=>"edit"} 

Domande:

  1. Sembra che l'indice e la Mostra azioni sono ridondanti. Dovrebbe essere rimosso uno di questi? Se sì, quale?
  2. Il parametro: id nell'azione Mostra non è necessario, poiché user_id è una chiave esterna nella tabella foos e vi è un solo foo per utente. Mi sbaglio?
  3. Mi piacerebbe avere un modo aggraziato per indirizzare alla nuova azione se non c'è un foo. Un'opzione potrebbe essere testare @ user.foo.nil? nell'azione Show o Index di FooController, quindi reindirizzare alla nuova azione. C'è un modo migliore?

Grazie per il vostro tempo.

risposta

25

Se il modello ha un'associazione has_one, provare a impostare il percorso utilizzando resource :foo (notare il nome del metodo singolare "risorsa", non "risorse"). Questo imposterà una rotta di risorse singleton (che ad esempio non ha azioni index e le azioni dei membri non hanno un parametro id poiché c'è un solo membro). Vedi anche http://apidock.com/rails/ActionController/Resources/resource (documentazione 2.3, ma si applica a 3.0 e afaik).

+2

Non riesco a credere che mi sia mancato. – craig

+1

Grazie per le informazioni –

2

Riesco a capire perché Craig lo abbia mancato. È una differenza così sottile che non mi è nemmeno passato per la testa. L'unica cosa che mi ha deluso è che le mie route nominate per la risorsa singleton hanno uno strano nome di indice: user_foo_index anziché user_foos.

È una deduzione davvero intelligente dall'assenza di plurale da parte di Rails.

Attenzione: Gli esempi seguenti utilizzano superficiale nidificazione da uno a fare questo:

resources :cats, shallow: true do 
    resources :noms 
end 

O che:

resources :cats do 
    shallow do 
    resources :noms 
    end 
end 

Comunque tornando al lavoro, se si imposta una risorsa singolare - address in contrasto con articles per esempio - e si vede qualcosa del genere:

user_address_index GET | POST 
    new_user_address GET 
     edit_address GET 
      address GET | PUT | DELETE 

Poi, come Andreas giustamente sottolineato, probabilmente erroneamente dichiarato questo nei vostri percorsi:

resources :users do 
    resources :address 
end 

E se si cambia quello a:

resources :users do 
    resource :address 
end 

Si dovrebbe essere tutto bene e felice e vedere qualcosa del genere se si preme rake routes nel prompt:

 user_address POST | GET | PUT | DELETE 
new_user_address GET 
edit_user_address GET 

Nota: So che l'output dei percorsi dei rakes non è esattamente uguale a questo (è molto più dettagliato), sto solo semplificando a scopo di concentrazione.

Spero che questo aiuti.