Ich habe eine Rails-App, mit der ein Benutzer eine Datenbankabfrage erstellen kann, indem er ein umfangreiches Formular ausfüllt. Ich habe mich über die beste Methode zur Überprüfung von Formularparametern in Rails Gedanken gemacht. Früher habe ich meine results
Methode (die eine zu dem macht die Form) hatte folgendes tun:Rails Formularvalidierung
if params[:name] && !params[:name].blank?
@name = params[:name]
else
flash[:error] = 'You must give a name'
redirect_to :action => 'index'
return
end
Aber für mehrere Formularfelder, sehen dies wiederholt für jede ermüdend bekam. Ich konnte nicht nur halten sie alle in irgendeiner Schleife für jedes Feld zu überprüfen, da die Felder unterschiedlich eingerichtet sind:
- ein einzelner Schlüssel:
params[:name]
- einen Schlüssel und einen Unterschlüssel:
params[:image][:font_size]
- nur einige Formularfelder erwarten ausgefüllt werden, wenn ein anderes Feld Dieser
etc. war auch wiederholend eingestellt war, weil ich flash[:error]
für jede fehlende/ungültige Parametereinstellung, und für jeden auf die gleiche URL umgeleitet wird. Ich wechselte auf eine before_filter
, die alle notwendigen Formularparameter überprüft und nur wahr zurückgibt, wenn alles in Ordnung ist. Dann wird das mein results
Verfahren geht weiter, und Variablen sind nur flat-out zugewiesen, ohne Kontrolle beteiligt:
@name = params[:name]
In meinem validate_form
Methode habe ich Abschnitte des Codes wie folgt aus:
if (
params[:analysis_type][:to_s] == 'development' ||
params[:results_to_generate].include?('graph')
)
{:graph_type => :to_s, :graph_width => :to_s,
:theme => :to_s}.each do |key, sub_key|
unless params[key] && params[key][sub_key]
flash[:error] = "Cannot leave '#{Inflector.humanize(key)}' blank"
redirect_to(url)
return false
end
end
end
I Ich habe mich nur gefragt, ob ich das am besten mache, oder ob mir etwas offensichtlich ist, wenn es um die Validierung von Parametern geht. Ich mache mir Sorgen, das ist immer noch nicht die effizienteste Technik, weil ich mehrere Blöcke habe, wo ich flash[:error]
einen Wert zuweisen, dann auf die gleiche URL umleiten und dann false zurückgeben.
bearbeiten zu klären: Der Grund, warum ich diese Validierung nicht in Modell (s), die derzeit aus zwei Gründen:
- Ich bin nicht zu sammeln Daten aus dem Benutzer, um versuchen, Erstellen oder aktualisieren Sie eine Zeile in der Datenbank. Keine der Daten, die der Benutzer übermittelt, werden nach dem Abmelden gespeichert. Es wird alles richtig verwendet, wenn sie es einreichen, um die Datenbank zu durchsuchen und einige Sachen zu erzeugen.
- Das Abfrageformular nimmt Daten zu mehreren Modellen auf und nimmt andere Daten auf, die überhaupt nicht zu einem Modell gehören. Z.B. Diagrammtyp und -thema, wie oben gezeigt, verbinden sich nicht mit irgendeinem Modell, sondern vermitteln lediglich Informationen darüber, wie der Benutzer seine Ergebnisse anzeigen möchte.
bearbeiten verbesserte Technik zeigen: I Verwendung von anwendungsspezifischen Ausnahmen machen Raising the Right Exception article jetzt dank Jamis Buck. Zum Beispiel:
def results
if params[:name] && !params[:name].blank?
@name = params[:name]
else
raise MyApp::MissingFieldError
end
if params[:age] && !params[:age].blank? && params[:age].numeric?
@age = params[:age].to_i
else
raise MyApp::MissingFieldError
end
rescue MyApp::MissingFieldError => err
flash[:error] = "Invalid form submission: #{err.clean_message}"
redirect_to :action => 'index'
end
Ich denke, dass Sie params [: name] und! Params [: name] .blank nicht verwenden müssen? in deinen Bedingungen. ! params [: Name] .blank? ist genug. params [: name] gibt false zurück, wenn es nil ist (es gibt keinen solchen Parameter) und params [: name] .blank? true zurück, wenn es null oder leer ist. – klew
Sie erhalten einen NoMethodError. Ich könnte NilClass überschreiben, um #blank hinzuzufügen? dazu nehme ich an. irb (main): 002: 0> params = {: a => 1,: b => 2,: c => 3} => {: c => 3,: a => 1,: b => 2} irb (main): 003: 0>! Params [: name] .blank? NoMethodError: undefinierte Methode 'leer? ' für nil: NilClass von (irb): 3 –
Kein Ruby hier, nur Rails. * deleted tag * – Nakilon