2016-08-08 37 views
0

Ich baue eine Ruby on Rails-Anwendung und ich bin oft mit dem Fehler erfüllen:Ruby on Rails, return 0 statt Fehler

TypeError: nil can't be coerced into Float 

oder String oder anderen Variablen-Typ, wenn ich eine Berechnung zu tun oder Fragen wie:

upcoming = Appointment.where(:hairdresser_id => hairdresser_id).where('status = ? OR status = ?', 'accepted', 'personal').map{|app| app.price}.reduce(0, :+) 

glaube ich, das Problem zu verstehen, aber Sie wissen, ob es eine einfache Möglichkeit ist I 0 anstelle von Fehlern wie das zurückgeben kann, weil sie hat ein Friseur vielleicht derzeit nicht akzeptiert kommen vor, dass Termine.

Eine Lösung könnte sein, zu überprüfen, ob alles existiert, bevor die Berechnung durchgeführt wird, aber ich bin mir sicher, dass dies nicht die beste Lösung sein wird!

Danke für die Hilfe!

+0

Ironischerweise ist die richtige Lösung, dies zu überprüfen Ding existiert vor der Berechnung. – mcfinnigan

+1

Versuchen Sie, 'Enumerable # compact' vor' reduce' zu ​​verwenden. Es entfernt "Null" -Werte. – Owen

Antwort

1

Wenn Appointment#price eine db Spalte können Sie eine zusätzliche Überprüfung hinzufügen:

.where.not(price: nil) 

Wenn es eine Methode ist oder ein virtuelles Attribut Sie können entweder den Wert in einen float oder int konvertieren, die Null konvertiert, um es numerische Darstellung von 0:

.map{ |app| app.price.to_f } # or `app.price.to_i` 

Oder Sie das Ergebnis mapcompact könnte, die die Einträge, die zu nil führen entfernt

.map{ |app| app.price }.compact 
+0

Mit .compact habe ich mein Problem gelöst! Ist dies die beste Vorgehensweise oder gibt es andere Möglichkeiten? – ste

+0

Wenn Sie zuvor Datensätze ausfiltern können, die nicht summiert werden können, wäre das der richtige Weg. Sehen Sie sich auch die Antwort von @lusketeer an, die möglicherweise passender ist, da er die Datensätze auf der db-Ebene bereits ausfiltert. – koffeinfrei

1

Angenommen, Ihre Assoziationen sind so eingerichtet, wie ich es mir vorstelle.

Erstens könnten wir die Termine von

Hairdresser.find(hairdresser_id).appointments 

Dann erhalten wir durch Status

Hairdresser.find(hairdresser_id).appointments.where("appointments.status" => ["personal", "accepted"]) 

Schließlich filtern können, wir sum Funktion zusammenzufassen die Preise ohne sich Gedanken über nil s nutzen können

upcoming = Hairdresser.find(hairdresser_id).appointments.where("appointments.status" => ["personal", "accepted"]).sum("appointments.price")