Benutzerdefinierte Parameter in der URL für die show-action
Arbeite ich an der Umsetzung einer SEO-hiarchy, was bedeutet, dass ich muss voranstellen Parameter für eine show-Aktion.
Der use-case ist eine such Seite wo die URL-Struktur ist:
/cars/(:brand)/
=> eine Liste Seite
/cars/(:brand)/(:model_name)?s=query_params
=> Suche Aktion
/cars/:brand/:model_name/:variant/:id
=> ein Auto-show-action
Mein problem ist, die show-action URLs funktionieren, ohne :brand
, :model_name
und :variant
als einzelne Argumente. Sie sind immer verfügbar, aus der die Werte für die Ressource.
Was ich habe:
/cars/19330-Audi-A4-3.0-TDI
Was ich will
/cars/Audi/A4/3.0-TDI/19330
Zuvor, wurde diese, wie die routes.rb
aussah:
# Before
resources :cars. only: [:show] do
member do
get 'favourize'
get 'unfavourize'
end
Folgenden war mein Erster Versuch:
# First attempt
scope '/cars/:brand/:model_name/:variant' do
match ":id" => 'cars_controller#show'
match ":car_id/favourize" => 'cars_controller#favourize', as: :favourize_car
match ":car_id/unfavourize" => 'cars_controller#unfavourize', as: :unfavourize_car
end
Dies macht es möglich:
cars_path(car, brand: car.brand, model_name: car.model_name, variant: car.variant)
Aber das ist natürlich nicht wirklich ideal.
Wie ist es möglich, um den setup-Routen (und vielleicht die .to_param
Methode?) in einer Weise, die nicht machen es eine mühsame Aufgabe, um das alles zu ändern link_to
Anrufe?
Vielen Dank im Voraus!
-- UPDATE --
Mit @tharrisson ' s Vorschlag, das ist, was ich versucht habe:
# routes.rb
match '/:brand/:model_name/:variant/:id' => 'cars#show', as: :car
# car.rb
def to_param
# Replace all non-alphanumeric chars with - , then merge adjacent dashes into one
"#{brand}/#{model_name}/#{variant.downcase.gsub(/[^[:alnum:]]/,'-').gsub(/-{2,}/,'-')}/#{id}"
end
Der route funktioniert einwandfrei, z.B. /cars/Audi/A4/3.0-TDI/19930
zeigt die richtige Seite. Die Generierung der link mit to_param
jedoch nicht funktioniert. Beispiel:
link_to "car link", car_path(@car)
#=> ActionView::Template::Error (No route matches {:controller=>"cars", :action=>"show", :locale=>"da", :brand=>#<Car id: 487143, (...)>})
link_to "car link 2", car_path(@car, brand: "Audi")
#=> ActionView::Template::Error (No route matches {:controller=>"cars", :action=>"show", :locale=>"da", :brand=>"Audi", :model_name=>#<Car id: 487143, (...)>})
Schienen nicht zu wissen scheint, wie zu übersetzen, die to_param in einem gültigen link.
- Dies ist eine wirklich gute und gut geschriebene Frage. Ich glaube, ich habe eine Idee und will sicherstellen, dass ich bin auf dem richtigen Weg (kein Wortspiel beabsichtigt). Ist es der Fall, dass Sie in der Lage sein zu verwenden
cars_path(@car)
in Ihrem link_to ' s aus, und generieren Sie die schöne hierarchische URL aus Ihren Ansichten,, sondern haben auch den router erkennen "teilweise" URLs (z.B./cars/Audi
) als Aufforderung zur Liste Audis? Oder ist es eine zusätzliche Anforderung für die link_to werden kontextuell bewusst (z.B. so schafft es die links zu der /cars/Marke-Variante von einigen controller-Aktionen, aber das volle Auto URL von den anderen controller-Aktionen? - Danke, @tharrison. Ich denke, du hast es richtig ist; ich möchte in der Lage sein zu verwenden
cars_path(@car)
in meinemlink_to
. Welche Aktion ausgelöst wird, kann gesteuert werden durch Einschränkungen in derroutes.rb
. Dies bedeutet, dass die urls fürcars/Audi
nicht verwendencars_path
aber so etwas wiebrand_path(brand: "Audi")
. - OK, die Anreise, aber ich weiß nicht so Recht, hab es dann :-). Wenn Sie möchten, verwenden Sie benannte Routen wie brand_path, die Argumentation wäre eine Instanz von der Marke, Modell ... obwohl, dass könnte sein, wie
brand_path(@car.brand)
. Haben Sie eine Marke, Modell und Ressourcen in die Routen für das? - Nein, es ist kein Modell für die "Marke", "model_name" und "Variante". Es mag scheinen, eingängig, aber es macht sehr viel Sinn 🙂 Neben das Auto-Objekt, es ist nur strings.
- Hab ihn -- Nein, das macht Sinn (zumindest für Modellname und-Varianten, möchten Sie vielleicht denken über die Marke, nur um sicherzustellen, dass die Konsistenz der Namensgebung, etc.), wollte nur sicher sein 🙂 OK, jetzt werde ich sehen, ob ich es herausfinden 🙂
- Genial! Ich wirklich zu schätzen.
- Ich denke, das ist, was du suchst: guides.rubyonrails.org/...
- Sie erstellen route nur für cars_path Helfer, siehe meine Antwort unten
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ich sehe keinen Weg, dies zu tun Schienen, ohne tweaking entweder die URL oder die Anerkennung oder die URL-Generierung.
Mit Ihrem ersten Versuch, hast du die URL-Erkennung funktioniert, aber nicht in der Erzeugung. Die Lösung, die ich sehen kann, um die generation arbeitet, würde das überschreiben der
car_path
Helfer-Methode.Andere Lösung könnte sein, wie Sie es in dem UPDATE zu überschreiben, die
to_param
Methode von dem Auto. Beachten Sie, dass Ihr problem nicht in derto_param
Methode, aber in der route-definition : Sie müssen:brand
,:model_name
und:variant
Parameter, wenn Sie möchten, erzeugen Sie die Strecke. Zu bewältigen, die Sie möglicherweise verwenden möchten, ein Wildcard-segment in Ihre route.Schließlich können Sie auch die routing-filter Juwel, die Sie in der Lage, zum hinzufügen von Logik vor und nach der url-Erkennung /generation.
Für mich sieht es so aus wie all diese Lösungen sind ein bisschen schwer und nicht so einfach wie es sein sollte, aber ich glaube, das kam von Ihr brauchen, wie Sie wollen hinzufügen, mehrere Ebenen in die URL ohne die streng nach den Schienen Verhalten, wird Ihnen die URL wie
/brands/audi/models/A3/variants/19930
OK, also hier ist was ich habe. Das funktioniert in meinem kleinen test-case. Offensichtlich einige Korrekturen nötig, und ich bin sicher, das könnte mehr sein, präzise und elegant, aber mein motto ist: "make it work, make it ziemlich, machen Sie schnell" 🙂
In
routes.rb
In der Auto-Modell
Und natürlich zerbrechlich und nicht TROCKEN, im
cars_controller.rb
match
Klauseln, wie erforderlich, durch Zugabe der:id
. Die ':as => :foo` argument ist, was ermöglicht es Ihnen, die URL-Referenz alsfoo_path
, und dieto_param
überschreiben, ist das, was produziert die ziemlich Pfad -- formatieren Sie es wie Sie wollen, und fügen Sie die id, oder was auch immer andere Attribute von Auto Sie möchten, um die schöne URL. Richtig?to_param
in einen link. Ich aktualisiert meine Frage mit einem einfachen Beispiel.Brauchen Sie nur zwei Routen erstellen, eine für die Anerkennung, die man für die Stromerzeugung.
Aktualisiert: verwenden Sie die Routen in Frage stellen.
Und anpassen
to_param
Beispiel der Pfad Helfer:
Du willst begrenzten Parameter zu übergeben, um url von denen einige Parameter sind optional, und einige von Ihnen streng muss vorhanden sein.
Rails guides zeigt, die Sie haben können strenge als auch optionale Parameter, und Sie können auch die Namen für bestimmte Strecke in Ordnung zu vereinfachen die Nutzung.
Guide on rails routing
gebundene Parameter
Beispiel -
Unten route,
brand
istoptional parameter
als seine umgeben voncircular bracket
Bitte beachten Sie, kann es sein, optionalen Parameter in der route, aber Sie muss Hinzugefügt letzten
/cars(/:brand)(/:make)(/:model)
match '/cars/(:brand)', :to => 'cars#index', :as => cars
hier
cars_url
Zuordnung zu index-Aktion von Autos controller..wieder
cars_url("Totoya")
leiten die index-action des Autos-controller zusammen-mitparams[:brand]
alsToyota
Show url-route sein kann, als unten, wo id ist obligatorisch, andere können optional sein
Im oben genannten Fall, der
id
Feld obligatorisch. Andere Parameter sind optional.so können Sie darauf zugreifen, wie
car_url(car.id)
odercar_url(12, 'toyota')
odercar_url(12, 'toyota', 'fortuner')
odercar_url(12, 'toyota', 'fortuner', 'something else)