Настройка маршрутов Rails на основе QueryString - PullRequest
15 голосов
/ 03 февраля 2011

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

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

... и если так, как это будет сделано?

Ответы [ 3 ]

16 голосов
/ 25 ноября 2011

Предполагая, что вы используете Rails 3+, вы можете использовать «Advanced Constraint» (подробнее о них читайте на 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
11 голосов
/ 04 октября 2014

Более кратко, чем ответ @ 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 голосов
/ 04 февраля 2011

Если оставить в стороне вопрос о том, разумно ли это сделать, ответ «возможно ли это» - «да»:

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>'

...