Имя и значение параметра (независимо) как часть Rails Route - PullRequest
1 голос
/ 04 декабря 2008

DocumentsController # common_query может обрабатывать несколько различных стилей запроса.

т.е. все документы в пакете 4 или все документы с меткой "счастливый"

Я хочу, чтобы один маршрут сделал их красивыми, поэтому:

/ документы / common_query? Партия = 4

/ документы / common_query? Тег = счастлив

стать:

/ документы / партии / 4

/ документы / теги / счастливый

Таким образом, конечным результатом является то, что #common_query вызывается, но часть URL-адреса использовалась в качестве имени параметра, а часть - в качестве его значения.

Ответы [ 2 ]

1 голос
/ 04 декабря 2008

Второй вариант, с двумя маршрутами, почти наверняка является лучшим способом, потому что он будет соответствовать только тем типам URL, которые вы хотите поддерживать, в то время как первый вариант также будет "соответствовать" URL-адресам, таким как / documents / foo / bar, которая, скорее всего, приведет к тому, что ваш метод #common_query в лучшем случае вернет ответ RecordNotFound (404). В худшем случае, если вы не готовы увидеть ни один из ожидаемых параметров, вместо этого вы получите ошибку 500 ...

Конечно, если у вас много вариантов, у вас будет много маршрутов. И если вам нужно использовать их в комбинации, например, / documents / batch / 4 / tag / happy, вам нужно будет использовать маршрутный символ и выполнять обработку параметров в вашем контроллере. Это может выглядеть примерно так:

map.connect 'documents/*specs', :controller => "documents_controller", :action => "common_query"

Различные элементы URL будут доступны вашему контроллеру в виде params [: specs]. Вы можете превратить это в находку так:

@items = Item.find(:all, :conditions => Hash[params[:specs]])

Эта техника Hash [] преобразует одномерный массив опций в хеш-ключ-значение, что может быть полезно, даже если вы не передаете его напрямую в find ().

0 голосов
/ 04 декабря 2008

Как одиночный маршрут:

ActionController::Routing::Routes.draw do |map|
  map.connect "documents/:type/:id", :controller => "documents_controller", 
              :action => "common_query"
end

Тогда params[:type] будет "batch" или "tag", а params[:id] или "4" или "happy". Вам нужно будет убедиться, что другие действия для DocumentsController выполняются до этого в маршрутах, потому что это будет соответствовать любому URL, который выглядит как "documents/*/*".

Но почему это должен быть один маршрут? Вы можете использовать два маршрута, как это:

map.with_options(:controller => "documents_controller", 
                 :action => "common_query") do |c|
  c.connect "documents/batch/:page", :type => "batch"
  c.connect "documents/tag/:tag",    :type => "tag"
end

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

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