2016-11-09 1 views
4

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

Так, например:

id: 1 
name: 'About' 
slug: 'about' 
parent_id: null 

id: 2 
name: 'Team' 
slug: 'team' 
parent_id: 1 

id: 3 
name: 'Cameron' 
slug: 'cameron' 
parent_id: 2 

Оторочка используется для доступа к ним с помощью маршрутизации, как так:

match '/:slug' => 'pages#show', :via => :get, :as => :page 

Так что я мог бы получить доступ к этим страницам по адресу:

/about 
/team 
/cameron 

То, что я хочу сделать, это использовать parent_id, так что маршрутизация будет:

/about/team/cameron 

Может ли это быть достигнуто только с помощью маршрутизации? Или мне нужно сделать что-то еще?

ответ

0

Обратиться за помощью в Friendly gem, это упрощает маршрутизацию с помощью слизней.

Альтернативных вариантов для определения маршрутов как

Насколько я знаю, нет хорошего способа маршрутов с динамическим paramlinks, вы можете создать именованный маршрут, чтобы захватить довольно вложенную страницу пути:

get '/p/*id', :to => 'pages#show', :as => :nested_pages 

Также , убедитесь, что вы обновили slug вашего объекта страницы, чтобы иметь вложенные URL-адреса, то есть: добавить к нему родительские страницы. Например:

page1.slug = '/about' 
page2.slug = '/about/team' # team is a child of about 
page3.slug = '/about/team/cameron' # cameron is a child of team 

, так что вы можете сделать это, как этот

get '/p/*id', :to => 'pages#show', :via => :get, :as => :nested_pages or pages 

Так, чтобы сделать эту работу, вы, вероятно, может изменить generate_slug метод в Page модели класса:

def generate_slug 
    name_as_slug = name.parameterize 
    if parent.present? 
    self.slug = [parent.slug, (slug.blank? ? name_as_slug : slug.split('/').last)].join('/') 
    else 
    self.slug = name_as_slug if slug.blank? 
    end 
end 
+0

Мне действительно очень нравится это для создания постоянной ссылки. Я изменил ваш код так: 'def generate_permalink name_as_permalink = slug.parameterize if parent_id.present? parent = Page.where (: id => parent_id) .first self.permalink = [parent.permalink, (permalink.blank?? Name_as_permalink: permalink.split ('/'). Last)]. Join ('/ ') еще self.permalink = name_as_permalink, если permalink.blank? end end' – Cameron

+0

Thanks cameron Он также может отлично работать –

1

Вы не можете достичь этого с помощью вложенных маршрутов, но вы можете с route globbing and wildcards. Позвольте мне изложить шаги, которые, вероятно, требуется, чтобы понять это, для вас:

  1. Добавить дикий маршрут карты, как get '*path', to: 'pages#show' до конца файла маршрутов, в противном случае он будет соответствовать всем другим запросам GET.
  2. Получите отчет для params['path'] в действии pages#show.

Начните с последнего сегмента и попробуйте его найти. Если вы его не нашли, страница не существует. Если вы получите результаты для последнего сегмента slug, проверьте их родителей, если они совпадают со следующим сегментом slug и так далее.

Если это будет огромное дерево, это решение, вероятно, создает проблему с производительностью. Затем вы можете реализовать что-то, что где-то хранит путь, или использовать такие решения, как PostgreSQL ltree.

+0

«Если вы получили результаты для последнего сегмента слизняков, проверьте их родителей, если они соответствуют следующему сегменту слизняков и так далее». Не могли бы вы показать пример того, как я могу это сделать? – Cameron

+0

Возможно, что-то вроде https://gist.github.com/openscript/7199e9b5515c45a4b7bc05d23dd7e9aa будет работать.Это своего рода псевдо-рубиновый код. Вам нужно адаптировать несколько вещей. – Robin

+0

Не интересуемся ли мы последней страницей пули? Зачем вам нужно перебирать остальные страницы? – Cameron