Имя и значение параметра (независимо) как часть маршрута Rails

StackOverflow https://stackoverflow.com/questions/339706

  •  19-08-2019
  •  | 
  •  

Вопрос

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

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

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

/documents/common_query?пакет =4

/documents/common_query?тег=счастливый

стать:

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

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

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

Это было полезно?

Решение

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

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

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

Другие советы

Второй вариант с двумя маршрутами почти наверняка является лучшим вариантом, потому что он будет соответствовать только тем типам 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-адреса будут доступны вашему контроллеру в виде параметров[:specs].Вы могли бы превратить это в находку вот так:

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top