2010-07-27 6 views
10

У меня есть два класса:Rails 3 HAS_ONE маршрутизации

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

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

Foo является необязательным.

Я создал следующий маршрут:

resources :users do 
    resources :foo 
end 

что приводит к следующим маршрутам:

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

Вопросы:

  1. Похоже, индексировать и показывать действия являются избыточными. Должен ли один из них быть удален? Если да, то какой?
  2. Параметр: id в действии Show кажется ненужным, так как user_id является внешним ключом в таблице foos, и для пользователя есть только один foo. Я ошибаюсь?
  3. Я хотел бы иметь изящный способ маршрута к новому действию, если нет foo. Один из вариантов - проверить @ user.foo.nil? в действии FooController Show или Index, затем перенаправляйте на новое действие. Есть ли способ лучше?

Спасибо за ваше время.

ответ

25

Если ваша модель имеет ассоциацию has_one, попробуйте настроить маршрут с помощью resource :foo (обратите внимание на уникальное имя метода «resource», а не «ресурсы»). Это установит одноуровневый маршрут ресурса (который, например, не имеет действия по индексу, а действия элемента не имеют параметра id, так как есть только один элемент). См. Также http://apidock.com/rails/ActionController/Resources/resource (2.3 документация, но относится и к 3.0, а также к афайку).

+2

Не могу поверить, что я пропустил это. – craig

+1

Спасибо за информацию –

2

Я могу понять, почему Крейг пропустил это на самом деле. Это такая тонкая разница, которую я даже не передумал. Единственное, что меня опрокинуло, это то, что мои именованные маршруты для ресурса singleton имеют странное имя индекса: user_foo_index вместо user_foos.

Это действительно умный вывод из-за отсутствия множественного числа со стороны Rails.

Предупреждение: Следующие примеры используют неглубокую вложенности либо делают это:

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

Или:

resources :cats do 
    shallow do 
    resources :noms 
    end 
end 

Во всяком случае вернуться к делу, если вы настроите сингулярный ресурс - address в отличие от articles например - и вы видите примерно следующее:

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

Тогда Андреас справедливо указывал, вы, вероятно, неправильно объявил это в маршрутах:

resources :users do 
    resources :address 
end 

И если вы измените что:

resources :users do 
    resource :address 
end 

Вы должны быть все хорошо и счастливы и посмотрите что-нибудь подобное, если вы нажмете rake routes в ответ на запрос:

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

Примечание: Я знаю, что вывод маршрутов грабли выглядит не так (это намного больше подробностей), я просто упрощаю ради сосредоточения.

Надеюсь, что это поможет.

Смежные вопросы