2009-09-03 7 views
13

Beim Routing von Ressourcen in Rails wird das optionale Formatattribut automatisch an die generierten Routen angehängt. Dies ist so, dass die in Frage stehende Ressource entweder als XML, HTML usw. angefordert werden kann. Welche Formate tatsächlich erlaubt sind, wird normalerweise in der Steuerung unter Verwendung von respond_to beschrieben.So begrenzen Sie die Ressourcenformate in der Rails-Routendatei

Aber in vielen Fällen möchten Sie nur HTML unterstützen und es fühlt sich an wie ein Overhead, respond_to :html in jede Aktion in jedem Controller zu schreiben. Es wäre daher cool, wenn es eine Möglichkeit gäbe, erlaubte Inhaltstypen bereits beim Erstellen der Routen in der Datei routes.rb zu begrenzen, z.

Gibt es eine Möglichkeit, dies entweder nativ oder über ein Plugin zu erreichen?

P.S. Der übliche Weg, dies zu umgehen, besteht darin, das Problem einfach zu ignorieren und respond_to nicht in den Aktionen zu verwenden. Dies beschränkt jedoch nicht die erlaubten Inhaltstypen. Stattdessen wird erwartet, dass für jeden möglichen Inhaltstyp eine Vorlage im Sichtenverzeichnis vorhanden ist. Wenn einer bei Anforderung nicht existiert, löst das System einen HTTP 500-Fehler aus.

Antwort

1

In beiden Fällen möchten Sie nicht einen HTTP 500-Fehler? Wie in der zweiten Zeile des Beispiels, wenn jemand JSON anstelle von HTML oder XML angefordert hat, ist kein Fehlercode die entsprechende Antwort zurückgeben?

+1

Nein, ein 500-Fehler bedeutet, etwas schief gelaufen ist auf dem Server Diese Antwort wird kopiert von meiner vorherigen Antwort

. Wenn ein Inhaltstyp nicht unterstützt wird, handelt es sich nicht um einen Serverfehler - es handelt sich um einen Clientfehler (der Client hätte es nicht anfordern sollen). A 406 wäre der richtige Antwortcode. Siehe "HTTP Response Codes": http://www.sitepoint.com/blogs/2008/02/04/restful-rails-part-i/ –

+0

Sicher, wenn Sie am Ende von .xml oder die URL und dieses Format wird nicht unterstützt, dann sollten Sie 404 nicht gefunden zurückgeben. Es scheint etwas frech zu sein, die Verwendung von conneg zu ignorieren, indem man URLs für jeden Inhaltstyp erstellt, aber dann den Quellcode stiehlt, wenn es keinen gültigen Inhaltstyp im Accept-Header gibt! –

+0

Nun, Sie könnten einen Punkt haben - auch wenn dies tatsächlich so ist, wie Rails out of the box funktioniert. Aber das ist nicht der Punkt meiner Frage. Ich möchte dies immer noch an einer zentralen Stelle angeben (am besten die routes-Datei) - egal, ob dann ein 404 oder ein 406 bei einem Fehler zurückgegeben wird. –

3

Ich glaube, Sie in der Lage sind, so etwas zu tun:

respond_to do |format| 
    format.html 
    format.json { render :json => @things } 
    format.any { render :text => "Invalid format", :status => 403 } 
end 

Wenn der Benutzer anfordert, HTML oder JSon es werde es tun, wie es sollte, aber alles andere die „Invalid Format“ Text machen.

+0

das würde funktionieren, aber ich denke, er will das: Format von den Routen –

0

nicht tun:

def some_action 
    ... 
    respond_to do |format| 
    format.html 
    format.json { whatever } 
    format.any { whatever } 
    end 
end 

benutzen Sie einfach:

def some_action 
    ... 
end 

und Rails für some_action.html.erb zu suchen Standard oder was auch immer Format angefordert. Wenn Sie keine anderen Ansichten als html definieren, schlagen alle anderen Formate fehl, wenn Sie dazu aufgefordert werden.

+0

Ich denke, er möchte das: Format von den Routen auch ablegen –

5

Da Rails das Äquivalent eines Platzhalters verwendet, um Formate ".: Format" zu verarbeiten, ist es etwas schwieriger, Dinge auf der Routerseite zu verhindern.

Stattdessen ist es eine ziemlich einfache Möglichkeit, alle Nicht-HTML-Anfragen in einem Vorher-Filter abzufangen. Hier ist eine Möglichkeit, wie dies aussehen könnte:

ActionController :: RoutingErrors werden als 404-Fehler behandelt, was sinnvoll ist. Im Fall, dass Sie eine Aktion zu tun haben, die etwas anderes als HTML unterstützen muss, benutzen Sie einfach:

skip_before_filter :check_format, :only => ACTION_NAME 
6

Sie müssen diese Routen in einem Umfang wickeln, wenn Sie sie zu einem bestimmten Format beschränken wollen (zB html oder json). Constraints funktionieren in diesem Fall leider nicht wie erwartet.

Dies ist ein Beispiel für einen solchen Block ...

scope :format => true, :constraints => { :format => 'json' } do 
    get '/bar' => "bar#index_with_json" 
end 

Weitere Informationen finden Sie hier: https://github.com/rails/rails/issues/5548 hier ..

Rails Routes - Limiting the available formats for a resource

Verwandte Themen