Rails: сопоставление конфликтующих маршрутов путем определения параметров - PullRequest
0 голосов
/ 29 июня 2010

Эй! Я пытаюсь настроить маршруты в приложении Rails, чтобы в зависимости от типа передаваемого параметра Rails отправлял запрос другому действию.

У меня есть courses, у которого есть атрибут state, представляющий собой строку с двухбуквенным сокращением состояния. Когда пользователь посещает /courses/1, я хочу, чтобы Rails отображал действие show в контроллере courses (и передавал параметр как :id). Когда пользователь посещает /courses/CO, я хочу, чтобы Rails отображал действие index и передавал параметр как :state.

Так что /courses/1 будет эквивалентно

:controller => 'courses', :action => 'show', :id => '1'

И /courses/CO будет эквивалентно

:controller => 'courses', :action => 'index', :state => 'CO'

Я пробовал это:

map.resources :courses, :except => { :index, :show }
map.connect 'courses/:state', :controller => 'courses', :action => 'index', :state => /[A-Z]{2}/
map.connect 'courses/:id',    :controller => 'courses', :action => 'show', :id => /[0-9]+/

Но он ломается (сервер рельсов даже не запускается). Я обычно не делаю таких вещей с маршрутами, поэтому я не в курсе своих ноу-хау. Спасибо!

Редактировать: Исправлена ​​опечатка, спасибо JC.

Текущее решение выглядит так:

map.resources :courses, :except => [ :index, :show ]
  map.courses  '/courses',        :controller => 'courses', :action => 'index', :state => 'AL', :method => :get
  map.courses  '/courses/:state', :controller => 'courses', :action => 'index', :requirements => { :state => /[A-Z]{2}/ }, :method => :get
  map.course   '/courses/:id',    :controller => 'courses', :action => 'show',  :requirements => { :id => /[0-9]+/      }, :method => :get

Ответы [ 2 ]

3 голосов
/ 29 июня 2010

Это работает, но вам нужно будет отредактировать все ваши ссылки на индекс, чтобы сказать что-то вроде courses_path('AA'), и вы не сможете использовать некоторые из хороших помощников, таких как form_for, которые предполагают, что вы следуете за Соглашение о том, что #create - это просто #index с запросом POST. (Освоиться с form_tag)

ActionController::Routing::Routes.draw do |map|
  map.resources :courses, :except => [ :index, :show ]
  map.courses  '/courses/:state', :controller => 'courses', :action => 'index', :requirements => { :state => /[A-Z]{2}/ } , :method => :get
  map.course   '/courses/:id',    :controller => 'courses', :action => 'show',  :requirements => { :id => /[0-9]+/      } , :method => :get
end

Тем не менее, ваши маршруты будут называться одинаково.

(кстати, ваш / co не соответствует вашему регулярному выражению, для которого требуются символы верхнего регистра)


Забавно: нам действительно нужна абстракция маршрутизатора? http://blog.peepcode.com/tutorials/2010/rethinking-rails-3-routes

0 голосов
/ 29 июня 2010

Боюсь, это не сработает, поскольку структура, которая отображает пути к контроллерам и действиям, настраивается при запуске приложения rails, обработка параметров происходит во время запроса.

Что вы можете сделать, этосопоставьте параметр: id в действии show в CoursesController со списком допустимых состояний, а затем либо перенаправьте, либо отобразите другое действие.

Надеюсь, это поможет.

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