0

Wie könnte man dieses Bit von Ruby on Rails-Code umgestalten?Refactoring-Bedingung mit einem Bereich von Werten

def select_plan 
     unless params[:plan] && (params[:plan] == '1' || params[:plan] == '2' || params[:plan] == '3' || params[:plan] == '4' || params[:plan] == '5' || params[:plan] == '6' || params[:plan] == '7' || params[:plan] == '8') 
      flash[:notice] = "Please select a membership plan to register." 
      redirect_to root_url 
     end 
    end 
+0

Woher kommen die gültigen Plannummern? Kommen sie aus einer Datenbank? Gibt es eine Konstante, die sie irgendwo definiert? Sind es magische Zahlen, die im gesamten Code verstreut sind? –

+0

Ich frage, weil die Tatsache, dass Sie die "6 ist ein gültiger Plan" haben, nur in einer Controller-Methode oder an mehreren verschiedenen Orten sitzt, was Sie refaktorisieren müssen, nicht die umständliche Implementierung, die Sie in 'select_plan' haben. Beheben Sie das zugrunde liegende Problem und 'select_plan 'wird sich als Nebeneffekt aufräumen. –

+0

@muistooshort - Bitte entschuldigen Sie meine Erfahrung. Die gültigen Plannummern sind in der Datenbank vorhanden. Ich bin daran interessiert, was Sie zu sagen haben. Ich bin mir nicht ganz sicher, ob du das meinst. –

Antwort

0

Wenn die Plannummern in der Datenbank vorhanden sind, und es ist ein Plan Modell dann könnte man einfach sagen, so etwas wie:

@plan = Plan.find_by(:id => params[:plan]) 
if([email protected]) 
    flash[:notice] = "Please select a membership plan to register." 
    redirect_to root_url 
end 

Jetzt Sie haben Zugriff auf die vollständigen Plandetails für die nächste Ansicht, so dass Sie ihnen den Namen, die Beschreibung, den Preis usw. anzeigen können. Das Vorhandensein eines Plans wird nur an einem Ort (dh in der Datenbank) gespeichert. Wenn Sie nicht @plan brauchen dann könnte man sagen:

if(!Plan.where(:id => params[:plan]).exists?) 
    ... 
end 

Der wichtige Punkt ist, dass es genau eine Sache sein, die weiß, was die gültigen Pläne sind und jederzeit Sie brauchen, um über Pläne zu wissen, fragen Sie, dass eine Sache und nur diese eine Sache.

Die Ansicht, dass select_plan auch die Datenbank (anstelle den wörtlichen Zahlen eins bis acht) verwenden würde Aufruf endet, um die gültigen Pläne zu erhalten:

<% Plan.order(...).each do |p| %> 
    whatever you need to display the plan as an option... 
<% end %> 

einen neuen Plan zur Datenbank hinzufügen und alles noch funktioniert . Entferne/deaktiviere einen Plan und alles funktioniert noch. Ihre Software wird einfacher zu warten sein, weniger Bugs haben, leichter zu verstehen sein, und Sie werden eine neue gute Angewohnheit und keine schlechte bekommen.

+1

Ich freue mich, dass Sie sich die Zeit genommen haben, Beispiele für die richtige RoR zu erklären und zu liefern. Ich habe die erste Lösung implementiert. –

3

Ich würde so etwas tun.

def select_plan 
    unless params[:plan].in?('1'..'8') 
    flash[:notice] = "Please select a membership plan to register." 
    redirect_to root_url 
    end 
end 

Oder wie mu ist zu kurz vorgeschlagen: Machen Sie Plan eine reale Sache. Es könnte ein Datenbankmodell oder nur eine kleine Ruby-Klasse sein:

# in app/models/plan.rb 
require 'set' 
class Plan 
    VALID_PLANS = Set.new('1'..'8').freeze 

    def self.valid_plan?(plan) 
    VALID_PLANS.include?(plan) 
    end 
end 

# used like 
def select_plan 
    unless Plan.valid_plan?(params[:plan]) 
    flash[:notice] = "Please select a membership plan to register." 
    redirect_to root_url 
    end 
end 
+0

Ich denke, dass Sie das eigentliche Problem hier vermissen. "Wie schreibe ich diese' if' Aussage "ist das Oberflächenproblem, das wirkliche Problem ist" wie weiß ich, ob 'params [: plan]' ist ein gültiger Plan ". –

+0

@muistooshort, verstehe ich nicht. Das scheint mir beides zu sein. –

+0

@CarySwoveland: Vermutlich ist ein "Plan" ein grundlegender Teil der Anwendung, so dass mir die verfügbaren Plannummern als ein paar magische Zahlen in einer Controller-Methode als eine wirklich schlechte Idee erscheinen. Es sollte ein "Plan" -Modell geben, das weiß, was die gültigen Plannummern sind, dann würde der Controller einfach "Plan" fragen, wenn "params [: plan]" gültig wäre und "Plan" würde wahrscheinlich eine Datenbank konsultieren. Der Code als isoliertes Stück ist in Ordnung, aber es riecht im Kontext der gesamten Anwendung schlecht. –