2010-08-04 9 views
11

In meinem Controller-Controller habe ich Date.new verwenden, um ein Datum Objekt zu erstellen, um in meinem ActiveRecord übergeben werden.raise ActiveRecord :: RecordNotFound (oder irgendeinen 404-Status) für ungültiges Datum

end_range = Date.new(params[:year].to_i, params[:month].to_i, params[:day].to_i).end_of_day.to_formatted_s(:db) 

Das Problem dabei ist, dass oben, wenn ein Benutzer versucht, die Parameter in der URL für den Tag 40 param als Eingabe manuell solche zu ändern, die Date.new ausfällt (wie erwartet). Allerdings hätte ich lieber keinen 500er Fehler, wenn ein Benutzer so etwas eintippte, sondern stattdessen einen 404 Fehler (weil man mit einem Tag 40 nie wirklich einen Datensatz erreichen kann).

Ich habe versucht, verschiedene conditionals (if und unless Aussagen) zu raise ActiveRecord::RecordNotFound wenn das nicht funktioniert, aber es gibt die 500-Fehler vor der bedingten läuft (und daher nie eine 404 zurückkehrt).

Kennt jemand einen besseren Weg, um das zu handhaben, oder eine Möglichkeit, die Date.new mehr würde fehlschlagen, so dass die bedingte Anweisung ausgeführt werden kann?

Antwort

28

In diesem Fall, dass Sie eine Ausnahme retten könnte und andere erhöhen, wenn Sie neu Karte Ausnahmen möchten, die nicht in der Art behandelt werden, die:

def show 
    begin 
    end_range = Date.new(...) 
    rescue ArgumentError 
    # Invalid date 
    raise ActiveRecord::RecordNotFound 
    end 
rescue ActiveRecord::RecordNotFound 
    render(:partial => 'not_found', :layout => 'application', :status => :not_found) 
end 

es effizienter sein könnte einfach rendern und scheitern sofort.

def show 
    begin 
    end_range = Date.new(...) 
    rescue ArgumentError 
    return render(:partial => 'date_not_found', :layout => 'application', :status => :not_found) 
    end 
end 

Sie können auch tun dies in einem weiten Sinne mit der rescue_from Methode der Application:

class ApplicationController < ActionController::Base 
    rescue_from 'ArgumentError do 
    render(:partial => 'exceptions/argument_error', :layout => 'application', :status => :not_found) 
    end 
end 
+0

Danke, das funktioniert. Das zweite Beispiel funktioniert gut, das war, was ich wollte, aber ich begann nur durch ein ActiveRecord NotFound zu versuchen, nur etwas anderes als 500 zu bekommen. (Wenn jemand liest, ist ActiveRecord im ersten Beispiel falsch eingegeben.) –

+0

Fixed der Tippfehler. Froh, dass das für dich funktioniert hat. – tadman

1

Ich denke, es macht mehr Sinn, einen ungültiges Datum Fehler mit einer nützlichen Nachricht zu retten. Dies ist ein häufiges Problem, wenn Benutzer beispielsweise den 30. Februar auswählen. Ich würde sie lieber zurück zum fraglichen Formular schicken und ihnen sagen, warum sie zurückgeschickt werden. Ein 404 wäre in den meisten Fällen falsch, da der Fehler eine ungültige Benutzereingabe und keine ungültige URL ist.

Weiter, wenn Sie alle ArgumentError s retten, dann werden Sie nicht über andere Code-Bugs benachrichtigt werden. Wenn es also kein Datumsfehler ist, richte ich den Fehler erneut aus. Leider müssen wir den Ausnahmetyp ändern, um eine Schleife zu vermeiden.

Ich habe dies in der application_controller setzen:

rescue_from ArgumentError do |exception| 
    if exception.message == 'invalid date' 
    flash[:error] = exception.message 
    redirect_to request.referer ? :back : root_url 
    else 
    raise StandardError, exception.message, exception.backtrace 
    end 
end 
+1

Diese Antwort ist besser, mehr Rails orientiert! – caesarsol

+1

StandardErrors werden nicht empfohlen. Sie sind einfach zu grundlegend und erklären keinen Kontext, nur die Tatsache, dass eine Ausnahme erhoben wurde. – maikovich

Verwandte Themen