2012-08-22 12 views
5

Ich habe diese Route:Keine Route Spiel in Controller-Spezifikation für meine komplexe Route

resources :items, path: 'feed', only: [:index], defaults: { variant: :feed } 

, die in der api und v1 Namespaces verschachtelt ist. (Die Parameter request_source stammt aus dem Api-Namespace).

Ich möchte die Indexaktion in meiner Controller-Spezifikation testen. Ich habe versucht:

get :feed, community_id: community.id, :request_source=>"api" 

nicht funktioniert, und so tut:

get :index, community_id: community.id, :request_source=>"api", variant: 'feed' 

sagen:

ActionController::RoutingError: 
    No route matches {:community_id=>"14", :request_source=>"api", :variant=>"feed", :controller=>"api/v1/items"} 

------- -------- EDIT -

Der Grund, warum ich die Variante verwenden möchte, um die Parameter an den Controller zu senden, ist, weil ich alle diese Routen habe:

resources :items, path: 'feed', only: [:index], defaults: { variant: 'feed' } 
    resources :items, path: 'popular', only: [:index], defaults: { variant: 'popular' } 

Dann in ItemsController, ich habe ein vor Filter "get_items" für den Index Aktion wich tut:

def get_items 
    if params[:variant] == 'feed' 
    .... 
elsif params[:variant] == 'popular' 
    .... 
end 
+0

Was ist der Backtrace auf die Ausnahme? –

Antwort

2

Es sieht aus wie das Problem herkommt defaults: { variant: :feed } definieren. Könnten Sie bitte erläutern, was Sie damit erreichen wollen?

habe ich eine Anwendung zu testen, was Sie haben und mit dem folgenden in config/routes.rb

namespace :api do 
    namespace :v1 do 
    resources :items, path: 'feed', only: :index 
    end 
end 

ich diese bekam, als ich rake routes lief.

$ rake routes 
api_v1_items GET /api/v1/feed(.:format) api/v1/items#index 

Update: für etwas einen Standard für die params Variable zu setzen, die nicht in der Route definiert ist, die Sie in Ihrem Handeln nutzen können.

params[:variant] ||= 'feed' 

Update 2: Sie params[:variant] in einem vor-Filter wie so bedingt zuweisen können.

class ItemsController < ApplicationController 
    before_filter :get_variant 

    # or more simply 
    # before_filter lambda { params[:variant] ||= 'feed' } 

    def index 
    render text: params[:variant] 
    end 

private  

    def get_variant 
    # make sure we have a default variant set 
    params[:variant] ||= 'feed' 
    end 
end 
+1

Wir haben viele Routen zu den Artikeln # index. Standardwert: {variant:: xxx} wird verwendet, um Parameter festzulegen, die das Verhalten der Indexaktion basierend auf der angeforderten Route bestimmen. – Alain

+0

@Alain es sieht so aus, als ob der 'defaults'-Hash die Standardeinstellungen für Routenparameter vorgibt. Wie zum Beispiel ': id' oder': format'.Sehen Sie mein Update –

+0

Sache ist, haben wir 3 Routen: Feed, beliebt und Index, die alle den gleichen Code verwenden (der aus Index), müssen wir nur etwas Setup vor dem Ausführen der Index-Aktion in einem vor Filter, die auf der: variante param. Dadurch können wir die Indexaktion wiederverwenden, ohne zusätzlichen Code in den Controller schreiben zu müssen. So wie wir es hätten tun müssen, wenn wir jede Route erstellt und in jeder Controller-Aktion Code hinzugefügt hätten, um die Indexseite zu rendern. Wenn du mir sagst, dass es keinen Weg gibt, diese Route funktionieren zu lassen, werde ich ein paar Tage warten (in der Hoffnung, dass du falsch liegst! ;-)) und dir dann das Kopfgeld geben. – Alain

0

Eine Idee, die ich eine Standardvariante setzen musste, könnte sein, den Pfad zu erlauben, dynamisch zu sein. Anstatt variant als Abfragezeichenfolge festzulegen, verwenden Sie sie als Teil des eigentlichen Pfads. Diese Methode benötigt keinen Vorher-Filter in Ihrem Controller.

namespace :api do 
    namespace :v1 do 
    root :to => 'items#index', :defaults => { :variant => 'feed' } 
    get ':variant' => 'items#index', :defaults => { :variant => 'feed' } 
    end 
end 

Dann könnte man die verschiedenen Bereiche auf der Website zugreifen mit

GET "http://localhost:3000/api/v1" # params[:variant] == 'feed' 
GET "http://localhost:3000/api/v1/feed" # params[:variant] == 'feed' 
GET "http://localhost:3000/api/v1/popular" # params[:variant] == 'popular' 
Verwandte Themen