2016-05-16 6 views
1

Ich habe folgendes Modell für den Urlaub. Was ich versuche, ist die Überprüfung der Zahl der verfügbaren Urlaubstage auf der Grundlage der Art des Urlaubs, des Urlaubs und der Urlaubszuweisung. Es sieht so aus, als würde mein 'check_leave' aus irgendeinem Grund nicht fehlerfrei validiert. Schätze jede Hilfe!Benutzerdefinierte Validierungsprüfung

class Leave < ActiveRecord::Base 
    belongs_to :staff 
    validates :staff, :leave_type, :start_date, :end_date, :number_of_days, :approved_by, presence: true 
    enum leave_type: {Medical: 0, Annual: 1, Urgent: 3, "Birth Leave": 4} 
    validate :check_leave, if: -> {self.number_of_days.present?} 

protected 

    def check_leave 
    if self.leave_type == 0 
     if (self.number_of_days = self.number_of_days + LeaveAllocation.last.medical_leave_counter) > LeaveAllocation.last.medical_leave 
     self.errors.add(:number_of_days, "Days exceeded the limit") 
     end 
    elsif self.leave_type == 1 
     if (self.number_of_days = self.number_of_days + LeaveAllocation.last.annual_leave_counter) > LeaveAllocation.last.annual_leave 
     self.errors.add(:number_of_days, "Days exceeded the limit") 
     end 
    end 
    end 
end 
+0

Was bedeutet "nicht funktioniert"? Fehler? Falsche Ergebnisse? Bitte geben Sie die Ausgabe von der Implementierung und dann erwartete Ausgabe, die zeigt, wie das zu identifizieren, wenn es funktioniert. –

+0

Es überprüft das check_leave überhaupt nicht.Kein Fehler –

+0

Sie sagen, dass 'validate' nicht * Ihre * check_leave' Methode aufruft? ODER sagen Sie, dass es ein logisches Problem in "check_leave" gibt, das dazu führt, dass Validierungen fehlschlagen? ODER sagst du, dass es ein logisches Problem in "check_leave" gibt, das dazu führt, dass es Validierungen übergibt, wenn nicht? ODER gibt es ein anderes Problem, das ich nicht erraten kann? –

Antwort

0

Es sieht für mich so aus, als müssten Sie nur die Zuweisung von self.number_of_days in Ihren Bedingungen (beide) entfernen. Wenn ich verstehe, was Sie suchen, dies sollte es tun:

def check_leave 
    if self.leave_type == 0 
    if (self.number_of_days + LeaveAllocation.last.medical_leave_counter) > LeaveAllocation.last.medical_leave 
     errors.add(:number_of_days, "Days exceeded the limit") 
    end 
    elsif self.leave_type == 1 
    if (self.number_of_days + LeaveAllocation.last.annual_leave_counter) > LeaveAllocation.last.annual_leave 
     errors.add(:number_of_days, "Days exceeded the limit") 
    end 
    end 
end 

ich auch die self. von errors.add entfernt, da es keinen Grund, es zu haben ist. Sie können wahrscheinlich alle Verwendungen von self. in dieser Methode entfernen, aber das überlasse ich Ihnen, falls es Konflikte gibt, die mir nicht bekannt sind.

Ich erstellte ein kurzes Testprogramm, um die Bedingungen mit einigen repräsentativen Daten zu testen, die ich erstellt habe. Das Testprogramm ist hier:

test_data = [ 
    { leave_type: 0, number_of_days: 2, leave_counter: 2, leave_limit: 13, result: true }, 
    { leave_type: 0, number_of_days: 12, leave_counter: 2, leave_limit: 13, result: false }, 
    { leave_type: 0, number_of_days: 12, leave_counter: 2, leave_limit: 14, result: true }, 
    { leave_type: 1, number_of_days: 5, leave_counter: 1, leave_limit: 9, result: true }, 
    { leave_type: 1, number_of_days: 12, leave_counter: 2, leave_limit: 13, result: false }, 
    { leave_type: 1, number_of_days: 12, leave_counter: 2, leave_limit: 14, result: true }, 
] 

def check_leave(leave_type, number_of_days, leave_counter, leave_limit) 
    if leave_type == 0 
    if (number_of_days + leave_counter) > leave_limit 
     return false 
    end 
    elsif leave_type == 1 
    if (number_of_days + leave_counter) > leave_limit 
     return false 
    end 
    end 

    return true 
end 

test_data.each_with_index do |test, i| 
    puts "#{check_leave(test[:leave_type], test[:number_of_days], test[:leave_counter], test[:leave_limit]) == test[:result] ? 'Pass' : 'Fail'}: #{i}" 
end 

Die Ergebnisse sind hier:

Pass: 0 
Pass: 1 
Pass: 2 
Pass: 3 
Pass: 4 
Pass: 5 

Dies ist 6 spezifischen Testbedingungen, die die folgenden drei Bedingungen für jeden der 2 leave_types bestätigen:

  • (number_of_days + leave_counter) < leave_limit (Überschreiten der Gültigkeitsprüfung)
  • (Anzahl_der_Tage + Urlaubszähler)> leave_limit (erwarten Validierung gescheitert)
  • (number_of_days + leave_counter) == leave_limit (erwarten Validierung passieren)

Dies zeigt an, dass die Kontrollen funktionieren. Ein Fehler bei der Validierung, wenn er erwartet wird, liegt wahrscheinlich an schlechten Testdaten. Jeder der vier Felder in dieser Validierung verwendet wird, kann schlecht sein:

  • leave_type
  • number_of_days
  • leave_counter
  • leave_limit

Der einzige verbleibende Schritt ist, um die Daten zu bestätigen, die in der Anwendungstest für die Validierungen, die angeblich nicht funktionieren. Mindestens ein Satz Testdaten (Werte für die 4 Pflichtfelder) ist notwendig, um weiter zu machen.

+0

Danke, aber es gibt immer noch alles, wenn es nicht sein sollte (außer leer) –

+0

Ich kann nur blind Code ohne zu wissen, mit welchen Informationen Sie testen und was Sie als Ergebnis erwarten . Zum Beispiel ist bei Eingaben von 'leave_type = 0' und' number_of_days = 9', 'medical_leave_counter = 4' und' medical_leave = 23448' das erwartete Ergebnis eine fehlgeschlagene Validierung. Oder etwas ähnliches. So viel hängt davon ab, welche Daten Sie in Ihrer Datenbank haben, und es gibt keine Möglichkeit für mich herauszufinden, was funktionieren wird und was nicht, ohne Kenntnis von Ergebnissen von bekannten Eingaben zu haben. Mehrere Beispiele sind erforderlich, um Validierungen zu bestehen und zu beenden. –

+0

Wenn die Summe von 'number_of_days' und' medical_leave_counter' mehr ist als 'medical_leave', sollte es fehlschlagen und einen Fehler anzeigen. –

0

Versuchen Sie dies, da die leave_type ein Hash ist, dass Sie den richtigen Schlüssel zur Verfügung stellen müssen, den Wert zu erhalten ...

ändern

if self.leave_type == 0 
    ... 
    elsif self.leave_type == 1 
    ... 
    end 

zu

if self.leave_type[:Medical] == 0 
    ... 
    elsif self.leave_type[:Annual] == 1 
    ... 
    end 
+0

Ich bekomme TypeError keine implizite Umwandlung von Symbol in Integer –