#ruby-on-rails
#ruby-on-rails
Вопрос:
Я новичок в Rails (использую 3.1) и ищу URL, который выглядит примерно так:
domain.com/jobs/florida/orlando
Я понимаю, что это выходит за рамки обычного маршрута с действием и одним идентификатором, так каков наилучший способ сделать это? Подпадает ли это под вложенную маршрутизацию?
Подробнее — если кто-то зайдет на страницу / jobs, он увидит список штатов. Если они попадут на страницу / jobs / florida, они увидят список городов. И, наконец, если они попадут в / jobs / florida / orlando, они увидят список вакансий, открытых в Орландо.
Как бы выглядел мой маршрут? Должен ли я думать об этой структуре URL по-другому? Моя основная мотивация — SEO — эти страницы обычно не будут просматриваться зарегистрированными пользователями, только если они найдут сайт через результат поиска.
Спасибо!
Ответ №1:
Вам следует взглянуть на динамические сегменты из руководства rails. В принципе, ваш пример должен иметь маршрут, подобный этому:
get "/jobs(/:state(/:city))", :to => "jobs#index"
и в вашем index
действии в JobsController
вы проверяете, выбран ли у вас штат и выбран ли город. Если да, то отображается список заданий из этого региона, если нет, то отображается более глубокий уровень вложенности, чем ваш текущий уровень.
Если это поможет, вы можете распространить этот маршрут на 3 разных:
get "/jobs", :to => "jobs#index_without_state"
get "/jobs/:state", :to => "jobs#index_without_city"
get "/jobs/:state/:city", :to => "jobs#index"
или как вы считаете, но я думаю, что это чрезмерно разработано, и первое предложение не должно быть намного сложнее реализовать (особенно когда вы можете извлечь некоторую логику в before_filters, если у вас есть определенный сегмент из маршрута)
Ответ №2:
У меня была похожая проблема, и я решил ее следующим образом:
resources :jobs do
collection do
constraints :state_id => /[a-z-] / do
get ':state_id' => 'states#show', :as => :state
get ':state_id/:city_id' => 'cities#show', :as => :city
end
end
end
/jobs
перейдет кjobs#index
У вас не должно быть номеров в названиях ваших городов / штатов!
-
/jobs/florida
переходит вstates#show
с state_id = florida -
/jobs/new-york
переходит вstates#show
с state_id = Нью-Йорк -
/jobs/florida/orlando
переходит вcities#show
с city_id = Орландо
Теперь начинается самое интересное! Вы также можете использовать slugs для своих заданий:
/jobs/1234-experienced-senior-programmer
переходит кjobs#show
с1234-experienced-senior-programmer
в качестве идентификатора, просто сделайтеparams[:id].to_i
, и вы получите идентификатор 1234 🙂
Не самая веселая часть:
такие методы сбора, как /jobs/new
, больше не будут работать — вы могли бы изменить это, добавив квантификатор, подобный :state_id => /[a-z-]{4,}/
поэтому для этого требуется, чтобы имена состояний содержали не менее 4 символов, а все 3-буквенные методы сбора, такие как new
, будут переданы контроллеру заданий как обычно
сгенерированные маршруты:
state_jobs GET /jobs/:state_id(.:format) {:controller=>"states", :state_id=>/[a-z-] /, :action=>"show"}
city_jobs GET /jobs/:state_id/:city_id(.:format) {:controller=>"cities", :state_id=>/[a-z-] /, :action=>"show"}
jobs GET /jobs(.:format) {:controller=>"jobs", :action=>"index"}
POST /jobs(.:format) {:controller=>"jobs", :action=>"create"}
new_job GET /jobs/new(.:format) {:controller=>"jobs", :action=>"new"}
edit_job GET /jobs/:id/edit(.:format) {:controller=>"jobs", :action=>"edit"}
job GET /jobs/:id(.:format) {:controller=>"jobs", :action=>"show"}
PUT /jobs/:id(.:format) {:controller=>"jobs", :action=>"update"}
DELETE /jobs/:id(.:format) {:controller=>"jobs", :action=>"destroy"}
Комментарии:
1. Спасибо за объяснение этого. Это грандиозно!
Ответ №3:
Вы могли бы сделать это в своем файле routes.rb, если у вас фиксированная глубина
match 'jobs/:state/:city/:neighborhood' => "Jobs#show"
Затем в своем действии show вы можете искать параметры [: state], параметры [: city] и т.д. И загружать соответствующие задания.
Комментарии:
1. Все три ответа, приведенные до сих пор, были превосходными, я выбрал этот из-за его простоты. Спасибо за помощь новичку в rails!
2. Из 3 ответов вы выбрали тот, который не отвечает на ваш вопрос — для соответствия
/jobs
, и/jobs/florida
. Этот маршрут соответствует только полному пути.