2016-08-08 31 views
0

Ich versuche, so etwas zu tun:Variable in bedingten zugeordnet ist in derselben bedingten verwendet, wirft Fehler

if user = User.find_by(email: '[email protected]') && !user.activated? 
    # do something 
end 

aber ich erhalte eine Fehlermeldung, dass geworfen „keine Methode‚aktiviert‘für nil: NilClass“

Gibt es eine Möglichkeit für mich, diese Funktionalität ohne eine geschachtelte Bedingung zu erreichen?

+0

Sind Sie sicher, das ist genau das, was wie Ihr Code sieht? Ich glaube, das sollte funktionieren, denn wenn der Benutzer nicht gefunden wird, gibt es nil zurück, was zu false führt. – arjabbar

Antwort

2

Sie können mit den Kontrollfluss Operator and über den logischen Operator && wie so:

if user = User.find_by(email: '[email protected]') and !user.activated? 
    # do something 
    end 

Beispiel:

if a = 12 && a.even? 
    "Working" 
end 
#=> undefined method `even?' for nil:NilClass 
if b = 12 and b.even? 
    "Working" 
end 
#=> "Working" 

Diese sollten Sie die Ausnahmebehandlung in Bedingung hinzufügen funktioniert, weil and eine niedrigere Präzedenz als die Zuweisung hat, also wird die Zuweisung o ccur vor der zweiten bedingten Prüfung.

Solange Sie die found = in conditional, should be == Warnungen nicht stört.

Zweite Option:

Die andere Option ist explizite Klammern dh.

if a = 12 && a.even? 
    "Working" 
end 
#=> undefined method `even?' for nil:NilClass 
if (b = 12) && b.even? 
    "Working" 
end 
#=> "Working" 

funktioniert dies, weil die Klammern werden () zuerst ausgewertet werden, bevor die Bedingung ausgewertet wird, so dass die Zuordnung innerhalb der Pars auftreten wird und dann als Teil der bedingten ausgewertet werden.

More on Ruby Operator Precedence

+0

danke, das ist genau das, was ich gesucht habe – johnsona

+1

2.2.0: 001> puts "opopo" wenn user = "xxx" &&! User.nil ? => null 2.2.0: 002> puts "opopo" wenn user = "xxx" und! User.nil? (irb): 2: Warnung: gefunden = in bedingten, sollte sein == opopo => null Nicht der empfohlene Weg nach dem IRB betrifft. Ruhe, du kannst tun, was immer du magst Chef. –

+0

@MuaazRafi Ich bin mir bewusst, aber die Frage wurde gestellt und das ist die richtige Antwort. Manchmal macht der Kontrollfluss Sinn, selbst wenn Warnungen vorhanden sind, zum Beispiel 'send_email_message wenn user = User.find_by (Bedingungen) und user.email_opt_in?' Das funktioniert und sendet die E-Mail nur, wenn der Benutzer sich angemeldet hat. – engineersmnky

0

Nein, Sie können nicht die gleiche var in der gleichen Zeile zuweisen und verwenden, müssen Sie es aufteilen.

user = User.find_by(email: '[email protected]') 

if user && !user.activated? 
    # do something 
end 

Lassen Sie mich wissen, ob dies hilft. Sie können user.nil überprüfen? aber oben wird auch funktionieren.

+0

Deklarieren Sie die obige Variable und verwenden Sie diese Referenz, um Speicher zu sparen. –

+0

2.2.0: 001> puts "opopo" wenn user = "xxx" &&! User.nil? => null 2.2.0: 002> puts "opopo" wenn user = "xxx" und! User.nil? (rb): 2: Warnung: gefunden = bedingte sollte, OpopO => nil Nicht die empfohlene Methode gemäß irb == werden: P –

+0

keine gute Praxis zu erklären Vars in Ihrem wenn die Bedingungen Sie das überprüfen Handbuch. (irb): 2: Warnung: gefunden = bedingt, da Sie Ruhe sehen können, können Sie tun, was auch immer Sie mögen, Chef. –

0

Das ist der Fall, wenn ein Benutzer nicht gefunden wird.

if user = User.find_by(email: '[email protected]') && !user.try(:activated)? 
    # do something 
end 
+0

Dies funktioniert nicht, da es immer falsch ist, weil 'NilClass' nicht die aktivierte Methode hat und die Zuweisung nicht vor der zweiten bedingten Prüfung erfolgt ist. – engineersmnky

+0

es wird nur zum zweiten Teil der Anweisung nach dem Ausführen der Suche Abfrage zuerst kommen – titan