Ich möchte eine 404-Seite in Rails "fälschen". In PHP würde ich einfach einen Header mit dem Fehlercode als solchem senden:
header("HTTP/1.0 404 Not Found");
Wie geht das mit Rails?
quelle
Ich möchte eine 404-Seite in Rails "fälschen". In PHP würde ich einfach einen Header mit dem Fehlercode als solchem senden:
header("HTTP/1.0 404 Not Found");
Wie geht das mit Rails?
Rendern Sie 404 nicht selbst, es gibt keinen Grund dafür; In Rails ist diese Funktionalität bereits integriert. Wenn Sie eine 404-Seite anzeigen möchten, erstellen Sie eine render_404
Methode (oder not_found
wie ich sie nannte) ApplicationController
wie folgt:
def not_found
raise ActionController::RoutingError.new('Not Found')
end
Schienen handhaben auch AbstractController::ActionNotFound
und auf ActiveRecord::RecordNotFound
die gleiche Weise.
Dies macht zwei Dinge besser:
1) Es verwendet den in Rails integrierten rescue_from
Handler, um die 404-Seite zu rendern, und 2) es unterbricht die Ausführung Ihres Codes und lässt Sie nette Dinge tun wie:
user = User.find_by_email(params[:email]) or not_found
user.do_something!
ohne hässliche bedingte Aussagen schreiben zu müssen.
Als Bonus ist es auch in Tests super einfach zu handhaben. Zum Beispiel in einem rspec-Integrationstest:
# RSpec 1
lambda {
visit '/something/you/want/to/404'
}.should raise_error(ActionController::RoutingError)
# RSpec 2+
expect {
get '/something/you/want/to/404'
}.to raise_error(ActionController::RoutingError)
Und am wenigsten:
assert_raises(ActionController::RoutingError) do
get '/something/you/want/to/404'
end
ODER verweisen Sie auf weitere Informationen von Rails Render 404, die von einer Controller-Aktion nicht gefunden wurden
ActionController::RecordNotFound
ist die bessere Option?expect { visit '/something/you/want/to/404' }.to raise_error(ActionController::RoutingError)
/ via stackoverflow.com/a/1722839/993890HTTP 404 Status
Um einen 404-Header zurückzugeben, verwenden Sie einfach die
:status
Option für die Rendermethode.Wenn Sie die 404-Standardseite rendern möchten, können Sie das Feature in einer Methode extrahieren.
und nenne es in deiner Aktion
Wenn die Aktion die Fehlerseite rendern und stoppen soll, verwenden Sie einfach eine return-Anweisung.
ActiveRecord und HTTP 404
Denken Sie auch daran, dass Rails einige ActiveRecord-Fehler behebt, z. B. das
ActiveRecord::RecordNotFound
Anzeigen der 404-Fehlerseite.Sie müssen diese Aktion also nicht selbst retten
User.find
löst ein aus,ActiveRecord::RecordNotFound
wenn der Benutzer nicht existiert. Dies ist eine sehr mächtige Funktion. Schauen Sie sich den folgenden Code anSie können es vereinfachen, indem Sie den Scheck an Rails delegieren. Verwenden Sie einfach die Bang-Version.
quelle
Die neu ausgewählte Antwort von Steven Soroka ist knapp, aber nicht vollständig. Der Test selbst verbirgt die Tatsache, dass dies keine echte 404 zurückgibt - es gibt einen Status von 200 zurück - "Erfolg". Die ursprüngliche Antwort war näher, versuchte jedoch, das Layout so zu rendern, als wäre kein Fehler aufgetreten. Dies behebt alles:
Hier ist ein typischer Testsatz von mir für etwas, von dem ich erwarte, dass er 404 mit RSpec- und Shoulda-Matchern zurückgibt:
Diese gesunde Paranoia ermöglichte es mir, die Nichtübereinstimmung des Inhaltstyps zu erkennen, wenn alles andere pfirsichfarben aussah :) Ich überprüfe alle diese Elemente: zugewiesene Variablen, Antwortcode, Antwortinhaltstyp, gerenderte Vorlage, gerendertes Layout, Flash-Nachrichten.
Ich überspringe die Überprüfung des Inhaltstyps für Anwendungen, die ausschließlich HTML sind ... manchmal. Immerhin "überprüft ein Skeptiker ALLE Schubladen" :)
http://dilbert.com/strips/comic/1998-01-20/
Zu Ihrer Information: Ich empfehle nicht, auf Dinge zu testen, die in der Steuerung geschehen, dh "should_raise". Was Sie interessiert, ist die Ausgabe. Bei den oben genannten Tests konnte ich verschiedene Lösungen ausprobieren, und die Tests bleiben gleich, unabhängig davon, ob die Lösung eine Ausnahme, ein spezielles Rendering usw. auslöst.
quelle
render :text => 'Not Found', :status => :not_found
.config.consider_all_requests_local
Parameter in Ihrerenvironments/development.rb
Datei wahrscheinlich auf true gesetzt ist, eine 200 zurückgegeben wird . Wenn Sie einen Fehler, wie in der akzeptierten Lösung beschrieben, in Staging / ProduktionSie können auch die Renderdatei verwenden:
Wo können Sie wählen, ob Sie das Layout verwenden möchten oder nicht.
Eine andere Möglichkeit besteht darin, die Ausnahmen zu verwenden, um sie zu steuern:
quelle
Die ausgewählte Antwort funktioniert in Rails 3.1+ nicht, da der Fehlerbehandler auf eine Middleware verschoben wurde (siehe Github-Problem) ).
Hier ist die Lösung, mit der ich ziemlich zufrieden bin.
In
ApplicationController
:und in
application.rb
:Und in meinen Ressourcen (anzeigen, bearbeiten, aktualisieren, löschen):
Dies könnte sicherlich verbessert werden, aber zumindest habe ich unterschiedliche Ansichten für not_found und internal_error, ohne die Kernfunktionen von Rails zu überschreiben.
quelle
|| not_found
Teil jedoch nicht. Rufen Sie einfach auffind!
(beachten Sie den Knall), und es wird ActiveRecord :: RecordNotFound ausgelöst, wenn die Ressource nicht abgerufen werden kann. Fügen Sie außerdem ActiveRecord :: RecordNotFound in der if-Bedingung zum Array hinzu.StandardError
und nichtException
, nur für den Fall. Eigentlich werde ich die statische Standard-500-Seite verlassen und überhaupt keine benutzerdefinierten Seiten verwendenrender_500
, was bedeutet, dass ich explizit einerescue_from
Reihe von Fehlern im Zusammenhang mit 404diese werden dir helfen ...
Anwendungscontroller
Fehler Controller
Ansichten / Fehler / Fehler_404.html.haml
quelle
Fügen Sie dies einfach zu der Seite hinzu, die Sie auf der 404-Fehlerseite rendern möchten, und fertig.
quelle
Ich wollte einen "normalen" 404 für jeden angemeldeten Benutzer werfen, der kein Administrator ist, also schrieb ich am Ende so etwas in Rails 5:
quelle
quelle
Um die Fehlerbehandlung zu testen, können Sie Folgendes tun:
quelle
Wenn Sie mit verschiedenen 404 auf unterschiedliche Weise umgehen möchten, sollten Sie sie in Ihren Controllern abfangen. Auf diese Weise können Sie beispielsweise die Anzahl der von verschiedenen Benutzergruppen generierten 404s verfolgen, den Support mit Benutzern interagieren lassen, um herauszufinden, was schief gelaufen ist / welcher Teil der Benutzererfahrung möglicherweise optimiert werden muss, A / B-Tests durchführen usw.
Ich habe hier die Basislogik in ApplicationController platziert, aber sie kann auch in spezifischeren Controllern platziert werden, um nur für einen Controller eine spezielle Logik zu haben.
Der Grund, warum ich ein if mit ENV ['RESCUE_404'] verwende, ist, dass ich das Auslösen von AR :: RecordNotFound isoliert testen kann. In Tests kann ich diese ENV-Variable auf false setzen, und meine Rettung_von würde nicht ausgelöst. Auf diese Weise kann ich das Erhöhen getrennt von der bedingten 404-Logik testen.
quelle