Настройка маршрутов Rails на основе QueryString

Я видел похожие вопросы по этому поводу, но не совсем то, что я ищу... Забывая на мгновение мудрость этого, можно ли это сделать?...

/object/update/123?o=section    # ==> route to SectionController#update
/object/update/456?o=question   # ==> route to QuestionController#update

... и если да, то как это сделать?

Ответы

Ответ 1

Предполагая, что вы используете Rails 3+, вы можете использовать "Расширенное ограничение" (подробнее об этом читайте в http://guides.rubyonrails.org/routing.html#advanced-constraints),

Здесь, как решить ваш пример:

module SectionConstraint
  extend self

  def matches?(request)
    request.query_parameters["o"] == "section"
  end
end

module QuestionConstraint
  extend self

  def matches?(request)
    request.query_parameters["o"] == "question"
  end
end

Rails.application.routes.draw do
  match "/object/update/:id" => "section#update", :constraints => SectionConstraint
  match "/object/update/:id" => "question#update", :constraints => QuestionConstraint
end

Ответ 2

Более краткий, чем @moonmaster9000 ответьте только на routes.rb:

match "/object/update/:id" => "section#update", 
  :constraints => lambda { |request| request.params[:o] == "section" }
match "/object/update/:id" => "question#update", 
  :constraints => lambda { |request| request.params[:o] == "question" }

Ответ 3

Отбросив вопрос о том, разумно ли это сделать, ответ на вопрос "возможно ли это" - это "да":

class QueryControllerApp
  def self.call(env)
    controller_name = env['QUERY_STRING'].split('=').last
    controller = (controller_name.titleize.pluralize + "Controller").constantize
    controller.action(:update).call(env)
  rescue NameError
    raise "#{controller_name} is an invalid parameter"
  end
end

MyRailsApp::Application.routes.draw do
  put 'posts/update/:id' =>  QueryControllerApp
end

В основном, программа маршрутизации может принимать любое приложение Rack в качестве конечной точки. Наше простое приложение анализирует строку запроса, строит имя контроллера и вызывает метод ActionController action (который сам является приложением Rack). Не показано: как обрабатывать строки запроса в любом формате, отличном от 'o=<controller_name>'