В моем приложении для направляющих у меня есть довольно стандартные has_many отношения между двумя объектами. A Foo
имеет нуль или больше Bars
; a Bar
принадлежит точно один Foo
. И Нечто и Панель определяются единственным целочисленным Значением идентификатора. Эти значения уникальны через все их соответствующие экземпляры.
Панель является существованием, зависящим от Foo: не имеет никакого смысла иметь Панель без Нечто.
Существует два пути к УСПОКОИТЕЛЬНО ссылочным экземплярам этих классов. Учитывая Foo.id "100" и Bar.id "200":
Ссылка каждый Foo и Панель через их собственные маршруты URL "верхнего уровня", как так:
Ссылочная Панель как вложенный ресурс через его экземпляр Foo:
Мне нравятся вложенные маршруты в № 2, поскольку он более тесно представляет фактические отношения зависимости между объектами. Однако это, действительно кажется, включает большую дополнительную работу для очень небольшого количества усиления. Предположение, что я знаю о конкретной Панели, мне не должны говорить о конкретном Foo; я могу получить это из самой Панели. На самом деле я, вероятно, должен проверять направленного Foo везде, я иду (так, чтобы Вы не могли сделать/foo/150/bar/200, предположив, что Панель 200 не присвоена Foo 150). В конечном счете я не вижу то, что это приносит мне.
Так, есть ли какие-либо другие аргументы за или против этих двух схем маршрутизации?
Я заинтересован главным образом об УСПОКОИТЕЛЬНОМ, обновляет/показывает/удаляет к конкретным Панелям. Для получения списка Панелей для определенного Foo (который обычно является "индексным" действием в направляющих) имеет смысл иметь вложенный маршрут, такой как/foo/100/bar. Страница в этом маршруте могла так же легко связаться с/bar/x как/foo/100/bar/x все же.
Вы ищете неглубокие маршруты. Как вы отметили, идея иметь глубоко вложенный маршрут для таких вещей, как создает, обновления не требуется, поскольку вы напрямую нацеливаетесь на желаемую запись.
На самом деле я никогда не занимался мелкой маршрутизацией, поэтому я перейду к эпизоду с Railscast, в котором Райан Бейтс объясняет это, вероятно, лучше, чем я: 139 вложенных ресурсов .
Редактировать: Вы можете прочитать немного больше о руководствах по маршрутизации 3.8.4 .
Rails ' мелкое вложение дает нам лучшее из обоих миров: оно позволяет нам иметь специфичные для Foo маршруты там, где это имеет смысл (создать, создать, индексировать) и Bar- только маршруты в противном случае (показать, отредактировать, обновить, уничтожить).
К сожалению, новый DSL маршрутизации в Rails 3 (который я использую) еще не поддерживает неглубокую маршрутизацию (начиная с Beta 3). Похоже, что в разработке , но на сегодняшний день не работает.
Тем не менее, вы можете подделать это, сопоставив ресурс дважды, один раз вложенным и один раз мелким:
resources :foo do
resources :bar, :only => [:index, :new, :create]
end
resources :bar, :only => [:show, :edit, :update, :destroy]
Это будет волновать меня до тех пор, пока параметр: shallow снова не будет запущен.
Лично, если каждый Bar зависит от Foo, вариант № 2 имеет больше смысла. Например, если Foo - это блог, а Bar - это сообщение, гораздо логичнее получить доступ к конкретному сообщению по адресу example.bloghosting.com/blog/1/post/2
, чем к примеру . bloghosting.com/post/21
.
Сделайте это с последней версией Rails:
class Food < ActiveRecord::Base
has_many :bars
end
class Bar < ActiveRecord::Base
belongs_to :foo
end
Затем в маршрутизаторе Rails (/config/routes.rb):
map.resources :foos do |foo|
foo.resource :bars
end
Подробнее см. Rails Routing from Outside In ] и Документация по Rails API .
Как вы уже знаете, каждый элемент должен иметь уникальный адрес. Я бы предположил, что чем короче и проще адрес, тем лучше для всех участников - вашего кода маршрутизации, ваших клиентских приложений и т. Д. Если вы можете идентифицировать панель по ее уникальному идентификатору, я бы, вероятно, указал только это в URL-адресе.
Однако вам не нужно терять семантическую информацию о назначении Bar для Foo. Это может быть частью представления.
В качестве усовершенствования вы можете разрешить клиенту обращаться к Bar 200 как / foo / 100 / bar / 200, но затем перенаправлять на предпочтительный / bar / 200 / адрес, используя, например, 303 («См. Другое» ) отклик.