2011-02-03 24 views
14

Widziałem podobne pytania na ten temat, ale nie całkiem to, czego szukam ... Zapominając na chwilę mądrości to zrobić, jest to możliwe do zrób to? ...Konfigurowanie Szyny trasy w oparciu o QueryString

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

... a jeśli tak, jak to zrobić?

+0

widzę tylko redirect_ti opcji w sterowniku w tym przypadku – apneadiving

Odpowiedz

3

Pomijając kwestię czy jest mądry, aby to zrobić, odpowiedź „jest to możliwe” brzmi „tak”:

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 

Zasadniczo odwzorowujący trasa może przyjąć dowolną aplikację Rack jako punkt końcowy. Nasza prosta aplikacja analizuje ciąg zapytania, buduje nazwę kontrolera i wywołuje metodę ActionController action (która sama jest aplikacją typu Rack). Nie pokazano: jak radzić sobie z ciągów zapytań z dowolnym formacie innym niż 'o=<controller_name>'

+0

najlepiej jak potrafię powiedz, że jest to jedyny sposób na "przekierowanie" bez efektu ubocznego polegającego na usunięciu łańcucha zapytania. Dziękujemy @zetetic – SooDesuNe

+2

Zamiast '.split', aby uzyskać żądnięcie zapytania, użyłbym:' Rack :: Utils.parse_nested_query (env ["QUERY_STRING"]) ' – SooDesuNe

16

Zakładając, że używasz Rails 3+, można użyć „Advanced Wiązanie” (czytaj więcej o nich w http://guides.rubyonrails.org/routing.html#advanced-constraints).

Oto jak rozwiązać swój przykład:

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 
+0

Gdzie, w którym folderze powinien być napisany ten moduł? Jestem początkującym użytkownikiem RoR. – inquisitive

11

bardziej zwięzły niż odpowiedzi @moonmaster9000 „s tylko dla 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" }