Ruby on Rails 3: несколько маршрутов в одном пространстве имен - PullRequest
1 голос
/ 28 сентября 2010

URL-адреса моей страницы похожи на '/ about', а URL-адреса моего города - на '/ san-francisco'. Здесь нет перекрытия. Как я могу получить следующие маршруты, чтобы хорошо играть?

get '/:city_slug', :to => 'cities#show', :as => 'city'
get ':action', :controller => "site", :action => 'show'

Ответы [ 3 ]

1 голос
/ 28 сентября 2010

Я категорически не согласен с частью "перенаправления" ответа @ ryan.Это удвоит вашу связь с сервером - это будет работать, но это определенно не хорошее решение.Идея переупорядочения совершенно правильна.

Итак, у меня есть решение - я действительно не уверен, что оно в порядке, но, похоже, оно работает как-то.

В вашем маршруте.rb:

get ":slug", :to => "cities#show", :constraints => CityConstraint.new, :as => city
get ":slug", :to => "site#show", :as => page

В коде необходимо упомянуть две вещи:

  • : slug во втором случае - это довольно странно, но его нужно назватьтак же, как в первом маршруте.Мне не удалось справиться с ним: page, как в вашем случае.Но я думаю, что это не имеет большого значения
  • : ограничения - это нормально и задокументировано

Само ограничение состоит из следующего класса:

class CityConstraint
  def matches?(request)
    # The condition would normally go through ActiveRecord to test the 
    # existence of town dynamically
    towns = %w(london prague washington)
    towns.include?(request.params[:slug])
  end
end

Ограничение запускается (метод соответствует?) Каждый раз, когда в таблице маршрутизации есть попадание в правило с ограничением.Я считаю, что это то, что вам нужно.Вероятно, потребуется некоторая форма кэша, чтобы не убить производительность.

И, кстати, это решение является только теоретическим, и я никогда не использовал его в производстве.Было бы здорово, если бы кто-то это проверил: -)

1 голос
/ 28 сентября 2010

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

get ':slug', :to => "cities#show", :as => "city"
get ':page', :to => "site#show", :as => "page"

В действии show для CitiesController вы выполняете поиск и затем спасаете его, когда он вызывает ActiveRecord :: RecordNotFound.

def show
  @city = City.find_by_slug!(params[:slug])
  rescue ActiveRecord::RecordNotFound
    redirect_to(page_path(params[:slug])
end

Или вы знаете, вы можете просто определить маршрут для каждой из ваших страниц и остановить эту перенаправление перенапряжения.

get 'about', :controller => "site", :action => "show", :id => "about"
# and so on.
0 голосов
/ 28 августа 2012

URL моей страницы похожи на '/ about', а URL моих городов - на '/ san-francisco'.

Если вы не используете пространства имен для URL-адресов двух разных типов объектов, вы не сможете отличить их друг от друга, не выполнив дополнительную проверку по БД (дорогой) или жестко закодированному списку.городов / страниц (хрупкие) каждый раз, когда вы получаете запрос на любую страницу / город на вашем сайте.

Если вы, возможно, можете использовать пространство имен для URL-адресов, это лучший способ сделать это, поэтому имейте:

cities/san-fransisco

или

pages/about

в зависимости от того, что вы чувствуетеэто наиболее важно сохранить на корневом уровне.Если в любом случае есть страница / города, ваши пользователи могут держать их под этим, что позволяет им легко переходить на страницу городов и видеть соотношение между URL-адресами, а также позволяет позже отображать города / топ и т. Д. И т. Д.Маршруты будут тогда очевидны

get "cities/:slug", :to => "cities#show", :as => city
get ":slug", :to => "site#show", :as => page

и позволят избежать проблем с конфликтом.

Если вы должны держать города на корневом уровне, вы можете поместить страницы в / pages и оставить города в качестве корневого уровня.В противном случае вы застряли, выполняя дополнительную работу по определению маршрутов (поиск при каждом входе в маршрут).

Еще одна вещь, которую вы могли бы рассмотреть, это добавить числовой идентификатор в города, это поможет вам справиться с конфликтующими именами какну (довольно часто в США, очень часто в мире), так что у вас есть

/1-san-francisco
/2-san-francisco (San Francisco, Minnesota)

и для маршрутов:

get ":slug", :to => "cities#show", :as => city, :constraints => { :slug => /\d*-[\w]*/ }
get ":slug", :to => "site#show", :as => page

Или названия городов по странам (нам/ штат / и т. д.) - если у вас нет возможности их различить, вы, несомненно, столкнетесь с дублированием названий городов в какой-то момент.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...