0

In meiner Rails 5 + Postgres app ich eine Abfrage wie folgt machen:Rails 5 Active - überprüfen, ob alle Ergebnisse, bevor mit Methoden

user = User.where("name = ?", name).first.email 

Also das gibt mir die E-Mail des ersten Benutzers mit dem Namen.

Aber wenn kein Benutzer mit diesem Namen existiert ich eine Fehlermeldung erhalten:

NoMethodError (undefined method `email' for nil:NilClass)

Wie kann ich überprüfen, ob ich irgendwelche Ergebnisse, bevor die Methode? if-Klauseln

ich denken kann, wenn verschiedene Möglichkeiten, dies mit zu tun:

user = User.where("name = ?", name).first 

if user 
user_email = user.email 
end 

Aber dies scheint nicht die eleganteste Art und Weise zu sein und ich bin sicher, dass Rails hat eine bessere Art und Weise.

Antwort

2

Sie find_by verwenden können, gibt das Objekt oder nil wenn nichts gefunden wird.

user = User.find_by(name: name) 
if user 
    ... 
end 

Dass gesagt wird man noch die where Klausel verwendet haben könnte, wenn Sie mehr als ein Element zu erwarten.

users = User.where(name: name) 
if users.any? 
    user = users.first 
    ... 
end 

Dann gibt es noch eine andere Art und Weise, wie von Ruby 2.3 wo Sie

User.where(name: name).first&.name 

Die & kann verwendet werden, tun können, wenn Sie nicht sicher sind, ob das Objekt nil ist oder nicht, in diesem Fall die Die ganze Anweisung würde nil zurückgeben, wenn kein Benutzer gefunden wird.

+2

Es gibt auch 'try' in Rails, wenn Ruby nicht über' & .': 'User.where (Name: Name) .First.versuch (: name) '. Aber 'try' schluckt auch NoMethodErrors, die nicht von' nil' herrühren, also möchten Sie manchmal 'versuchen'. –

1

Ich benutze try viel gerade mit dieser Situation zu umgehen.

user = User.where("name = ?", name).first.try(:email) 

Es wird die E-Mail zurückzukehren, oder, wenn die Sammlung leer ist (und first ist gleich Null) wird es Null zurück, ohne einen Fehler zu erhöhen.

Der Catch ist, es wird auch nicht fehlschlagen, wenn der Datensatz gefunden wurde, aber keine Methode oder Attribut existiert, so dass Sie weniger wahrscheinlich einen Tippfehler bekommen, aber hoffentlich würden Ihre Tests das abdecken.

user = User.where("name = ?", name).first.try(:emial) 

Dies ist kein Problem, wenn Sie die Ruby-2.3 &. Funktion verwenden, da es mit nil Objekt funktioniert nur ...

user = User.where("name = ?", name).first&.emial 
# this will raise an error if the record is found but there's no emial attrib. 
-1

Sie immer User.where("name = ?", name).first&.email verwenden können, aber ich stimme nicht, dass

user = User.where("name = ?", name).first 

if user 
    user_email = user.email 
end 

ist besonders unelegant. Sie können es mit so etwas wie

def my_method 
    if user 
    # do something with user.email 
    end 
end 

private 

def user 
    @user ||= User.where("name = ?", name).first 
    # @user ||= User.find_by("name = ?", name) # can also be used here, and it preferred. 
end 

aufzuräumen Es sei denn, Sie wirklich, dass Sie gehen nur einmal den Benutzerdatensatz zu verwenden, sollten Sie mit dem Sein explizit bevorzugen, was auch immer Logik Sie verwenden.

Verwandte Themen