Вложенные в себя бесконечные маршруты

#ruby-on-rails #ruby #ruby-on-rails-4

#ruby-on-rails #ruby #ruby-on-rails-4

Вопрос:

Есть ли способ самостоятельно вложить ресурс в маршруты до бесконечности?

Предположим следующий сценарий: я хочу создать несколько страниц, которые могут быть самонастраивающимися друг в друга, например, страница продуктов содержит много страниц продукта, а каждая страница продукта имеет несколько подстраниц и т.д. Ресурс будет представлять собой страницу в древовидной структуре, как в awesome nested set gem .

В случае, если администратор может создавать страницы на неизвестном уровне глубины, как бы я создал маршруты?

Приведенный выше пример должен создавать URL, подобный /:friendly_id_of_level_1/:friendly_id_of_level_2/.../:friendly_id_of_level_n

Я пробовал использовать динамические маршруты, но у этого способа много недостатков.

Есть предложения?

Ответ №1:

Я делаю аналогичную вещь в одном из моих приложений с этим маршрутом:

 map.connect "/c/*modules", :controller => "content", :action => "show"
  

(Обратите внимание, что здесь используется синтаксис маршрутизации rails2, возможно, потребуется его обновить).

Это разрешит этот URL

 /c/123-foo/456-bar/789-baz/653-qux
  

к content#show действию с параметрами, установленными как

 params = {"modules"=>[123-foo", "456-bar", "789-baz", "653-qux"]}
  

Модули имеют древовидную структуру, поэтому я могу использовать последовательность идентификаторов модулей в params[:modules] для создания цепочки макетов и любых других иерархических данных, и я использую последнюю в массиве как «текущую», чтобы фактически показывать пользователю.

Примечание: я поставил «/c /» в начале URL-адреса, чтобы отделить эти вложенные маршруты от всех других моих маршрутов: в противном случае это очень жадно и будет соответствовать практически любому URL-адресу на вашем сайте. Это не проблема, если вы хотите всегда иметь его в качестве «общего» маршрута внизу вашего файла маршрутов, но если нет, то вам нужно будет добавить что-то, чтобы сделать его отличным. Очевидно, что это не обязательно должно быть «/ c /», у вас может быть что угодно, что остановит его столкновение с другими вашими маршрутами.

Комментарии:

1. привет и спасибо вам за ваш ответ. Что вы делаете в случае одинаковых имен модулей по разным путям? Как вы обрабатываете прямые URL-адреса в c / 653-qux, когда они должны быть / c / 123-foo / 456-bar / 789-baz / 653-qux или / c / 123-foo / 653-qux У вас нет конфликтов с ними?

2. Конфликта как такового нет: /c/653-qux и /c/123-foo/456-bar/789-baz/653-qux оба будут показывать страницу содержимого для модуля с идентификатором 653. ( 653-qux генерируется из метода to_param). Однако, если вы вызовете более длинный URL-адрес, вы также получите некоторую дополнительную информацию о пути, который вы перенесли к этому модулю, который можно использовать для создания панировочных сухарей.

3. Кстати, структура моего модуля не является строгим деревом «один ко многим»: она больше похожа на «многие ко многим», т. Е. Один и тот же дочерний элемент может находиться в нескольких разных родительских ветвях. Если бы у вас была строгая древовидная структура , где каждый дочерний элемент находится на одной ветви , тогда вы могли бы сгенерировать панировочные сухари , просмотрев предков 653-qux .

4. Я понимаю, что ты имеешь в виду. Хотя я имел в виду отношения «один ко многим», ваш подход «многие ко многим» также сложен. Это ограничивает ресурсы уникальностью атрибута, который генерирует URL-адрес. Но что в случае, если администратор идет и создает страницу типа products / info, а другую — как company / info ? Как сервер ответит на запрос /info? Тем не менее, я был вдохновлен вашим подходом и пытаюсь сделать что-то подобное, хотя, должен сказать, я немного беспокоюсь о случаях, подобных описанному выше.

5. Да, многие для многих требуют, чтобы вы использовали уникальные идентификаторы. Если бы это был один ко многим, то, как вы говорите, единственным требованием является то, чтобы ideintifiers были уникальными в пределах своих братьев и сестер. Однако это предполагает, что в дальнейшем кто-то не захочет использовать одну и ту же статью (или что-то еще) в двух отдельных местах. Может быть другой способ, позволяющий смешивать и сопоставлять. Если вам может сойти с рук наличие абсолютно уникальных идентификаторов (slugs или ids) в URL, я бы настоятельно рекомендовал это, поскольку это намного упрощает вашу жизнь.