2011-01-11 6 views
2

Ich verwende Rails 3. Und ich frage mich, wie man Params zu einigen Blöcken in routes.rb übergeben.Wie Params zu einem Block in Rails Routen übergeben?

Was ich versuche zu tun ist, eine catch all Route zu machen, überprüfen Sie von slugs Datenbank den Modellnamen von der ID.

Nachdem ich die model name bekommen habe, plurliere ich sie, um den Namen des Controllers zu erhalten.

match '/:id', :controller => proc { Slug.find_by_iid(params[:id]).model.pluralize }, :action => :show 

Die Tabelle slugs

model iid 
----- ----- 
post  4d2c7de0c5abe7f8a9000007 
item  4d2c7de0c5abe7f809000004 

Wenn ich versuche, ein paar Seiten wie /4d2c7de0c5abe7f8a9000007 zugreifen habe ich diesen Fehler:

Started GET "/4d2c7de0c5abe7f8a9000007" for 
127.0.0.1 at 2011-01-12 00:04:31 +0200 

ActionController::RoutingError (wrong constant name #<Proc:[email protected]): 

Rendered /Users/amr/.rvm/gems/[email protected]/gems/actionpack-3.0.3/lib/action_dispatch/middleware/templates/rescues/routing_error.erb within rescues/layout (1.2ms) 

Die erwartete ist # Blick auf Pfosten mit iid Punkt : 4d2c7de0c5abe7f8a9000007

Antwort

8

proc gibt einen Proc zurück, aber match erwartet eine Zeichenfolge. Sie könnten versuchen, .call hinzuzufügen, damit der Prozess seinen Wert zurückgibt. Obwohl ich bin mir nicht sicher, ob dies das proc jedes Mal rief am Ende oder nur, wenn routes geladen ...

EDIT

Scheint war ich weg-Basis mit meiner früheren Antwort und Kommentaren. Vielleicht so etwas ?:

match '/:id', :to => proc { |env| 
    id = env["action_dispatch.request.path_parameters"][:id] 
    model = Slug.find_by_iid(id).model 
    controller = [model.pluralize.camelize,"Controller"].join.constantize 
    controller.action("show").call(env) 
} 

Obwohl dies wirklich in einer Bibliothek definiert und enthalten sein sollte. Vielleicht kennt jemand einen besseren Weg?

+0

ich entfernen könnte 'proc' wie das' : controller => Slug.find_by_iid (params [: id]). model.pluralize' aber immer noch das Problem ist, wie man 'params [: id]' value bekommt. Wenn ich versuche, die App zu starten, wirft es mir einen Fehler '../config/routes.rb:6:in' Block in ': undefinierte lokale Variable oder Methode 'params' für # (NameError) ' – amrnt

+0

wenn ich es gemacht habe' controller => proc {Slug.find_by_id (params [: id]). Model.pluralize} .call' es warf mich '/config/routes.rb : 6: in 'block (2 levels) in ': undefinierte lokale Variable oder Methode' params' für # (NameError) 'AUCH! – amrnt

+0

Ahh, ich habe die 'Params' dort vermisst. Ich glaube nicht, dass das funktioniert - "params" ist in der Steuerung eingestellt, nicht die Routing-Engine. Werfen Sie einen Blick auf die Antwort hier: http://stackoverflow.com/questions/2596312/dynamic-url-controller-mapping-for-routes-in-Rails – zetetic

0

Putting dies in Ihre Routen scheint wirklich hacky. Ich würde empfehlen, einen Slugs-Controller zu erstellen, diesen Task an diesen zu übergeben und von dort auf den entsprechenden Controller umzuleiten. Angenommen, Ihre anderen Seiten Standard RESTful Routen verwenden, können Sie etwas tun:

Route ändern, um diese:

match '/:id', :controller => :slugs, :action => :show 

Slugs Controller:

def show 
    slug = Slug.find_by_iid(params[:id]) 

    redirect_to send("#{slug.model}_url", params[:id]) 
end 
+0

Ich möchte nicht umleiten dude! Ich möchte nur die Anwendung meinen Slug verstehen lassen und das zugehörige Modell laden. wie in facebook.com und quora.com – amrnt