2010-07-03 3 views
9

Ich arbeite an einer Ruby on Rails-Anwendung. Für einen Sitzungscontroller möchte ich einen Fall verwenden, um zu überprüfen, ob das Konto eines Benutzers gesperrt oder gesperrt ist. Ich versuche, das Objekt einer Klasse als den Fall zu verwenden, und zu verwenden, wenn Attribute überprüft werden.Ruby on Rails Gehäuse/Switch. Wie passt man gegen ein Objekt?

Zum Beispiel

user = Profile.find(1) 
case user 
when user.ban 
    redirect_to() 
when user.lock 
    redirect_to() 
else 
    redirect_to() 
end 

Das einzige Problem ist, dass nicht funktioniert.

Was bedeutet Arbeit ist dies:

case user.ban 
when true 
    redirect_to() 
else 
    redirect_to() 
end 

Irgendwelche Tipps, wie ich über die Überprüfung gehen kann, wenn ein Benutzerobjekt verboten oder gesperrt ist ein Schalter?

Danke

Antwort

19

Machen Sie eine user.status Methode, die einen Zustand eines Benutzers zurückgibt, dann können Sie dies tun:

user = Profile.find(1) 
case user.status 
when "banned" 
    redirect_to() 
when "locked" 
    redirect_to() 
else 
    redirect_to() 
end 
+0

Vielen Dank für die Antworten. Ich fand Zepplocks Antwort am nützlichsten für meine Anwendung. Der einzige Unterschied ist, dass ich Symbole in der Methode und im Fall verwendet habe. Hier ist die Methode, die ich schrieb: def Status wenn self.ban Rückkehr: Verbot Ende wenn self.lock Rückkehr: sperren Ende Ende – Brian

+0

@ Brian: Nur ein bisschen Rubify - wenn eine Funktion einen Booleschen Wert zurück, Es ist eine gute Form, es mit einem Fragezeichen zu benennen. Auch wenn Post-Modifikatoren missbraucht werden und die Lesbarkeit beeinträchtigen können, denke ich, dass sie in diesem Fall daran arbeiten, sie zu verbessern: 'def status; Rückkehr: verboten wenn verboten ?; return: gesperrt wenn gesperrt? ende – Amadan

0

Sie tun können, als Zepplock sagte. Aber für gegebenes Beispiel ist das folgende der beste Weg (nur ein Beispiel)

action_name = (user.ban)? "ban" : ((user.lock)? "lock" : "default") 
redirect_to(:action => action_name) 
13

Ich mag @ Salils Antwort; aber wenn Sie wirklich case möchten, können Sie dies tun:

case true 
    when user.ban 
    redirect_to() 
    when user.lock 
    redirect_to() 
    else 
    redirect_to() 
end 

UPDATE Jörg sagte, dies funktioniert auch, und er ist richtig! Gib ihm ein paar Stimmen über seine Antwort! (Wie ich)

case 
    when user.ban 
    redirect_to() 
    when user.lock 
    redirect_to() 
    else 
    redirect_to() 
end 

UPDATE 2012 Das funktioniert jetzt:

case user 
    when lambda(&:ban) 
    redirect_to() 
    when lambda(&:lock) 
    redirect_to() 
    else 
    redirect_to() 
    end 
end 
+0

+1 für nie jemals zu glauben, dass wahr als case bedingung. – Salil

+0

Ich denke, die Reihenfolge der when s ist verdammt wichtig, nicht wahr? Wie auch immer, +1 für so eine tolle Idee. –

+3

Dies ist unnötig kompliziert. Der Grund, warum dies funktioniert ist, dass "wahr === wahr" ist. Aber die andere Form des "Fall" -Ausdrucks, d. H. Einfach das "Wahre" ganz auszulassen, macht ohnehin das Gleiche. –

0

@ Brian, die Idee eines Schaltergehäuses ist, dass Sie eine Variable, die einen dynamischen Wert und prüft, akzeptiert es gegen einige konstante Werte. In dem Code, den Sie geschrieben haben, enthalten die Case-Anweisungen dynamische Werte wie user.ban, die von der Variablen selbst abhängen, die Sie überprüfen möchten. Wie @Zepplock funktioniert, ist der richtige Weg, um einen Switch-Fall zu verwenden.

2

Lol, ich liebe Amadans Antwort. Und wenn Sie wirklich eine case-Anweisung haben wollen, sollten Sie wahrscheinlich tun, was Zepplock gesagt hat (obwohl Sie Symbole anstelle von Strings betrachten könnten), aber basierend auf Ihrem Anwendungsfall möchten Sie eine if-statement-basierte Lösung wie Salils.

Wie auch immer, dachte, ich würde werfen und Spaß haben auch^_^ Hier ist eine Lösung, die mit dem funktioniert, was Sie sagten, es erstellt Objekte, die reagieren auf === (was Fall Anweisungen verwenden), dann Sie rufen die gewünschte Methode auf (Sperren oder Sperren) und geben sie zurück. Sie sollten sie wahrscheinlich in eine Art Config setzen oder initializer oder auf andere Weise speichern die Ergebnisse nach dem ersten Aufruf, um die Leistung zu sparen (App benötigt nur diese Objekte gleichzeitig erstellen)

user = Class.new do 
    def ban() true end 
    def lock() true end 
end.new 

def banned? 
    ban_checker = Object.new 
    def ban_checker.===(user) user.ban end 
    ban_checker 
end 

def locked? 
    lock_checker = Object.new 
    def lock_checker.===(user) user.lock end 
    lock_checker 
end 

case user 
when banned? 
    puts 'banned' 
when locked? 
    puts 'locked' 
else 
    puts 'default' 
end 

Hinweis: I Ich befürworte diese Lösung nicht, weil sie die Kapselung verletzt. Banned sollte für Ihren Benutzer definiert und verwendet werden, aber damit dies funktioniert, muss es im umschließenden Bereich definiert werden.Ich meistens dies für Spaß up bringen :)

7

einfach die user auslassen:

user = Profile.find(1) 
case 
when user.ban 
    redirect_to 
when user.lock 
    redirect_to 
else 
    redirect_to 
end 

In Ruby gibt es zwei Formen des case Ausdruck. In der obigen Form führt es einfach die erste Verzweigung aus, die einen gewöhnlichen Wert ergibt (d. H. Alles außer nil oder false).

Die andere Form

case foo 
when bar 
    baz 
end 

entspricht

if bar === foo 
    baz 
end