Überprüfen Sie, ob in der Rails-Verknüpfung nicht null und nicht leer ist.


74

Ich habe eine Show-Seite für meine Benutzer und jedes Attribut sollte nur auf dieser Seite sichtbar sein, wenn es nicht null und keine leere Zeichenfolge ist. Unten habe ich meinen Controller und es ist ziemlich ärgerlich, @user.city != nil && @user.city != ""für jede Variable die gleiche Codezeile schreiben zu müssen . Ich bin nicht sehr vertraut mit dem Erstellen eigener Methoden, aber kann ich irgendwie eine Verknüpfung erstellen, um so etwas zu tun : @city = check_attr(@user.city)? Oder gibt es eine bessere Möglichkeit, dieses Verfahren zu verkürzen?

users_controller.rb

def show 
  @city = @user.city != nil && @user.city != ""
  @state = @user.state != nil && @user.state != ""
  @bio = @user.bio != nil && @user.bio != ""
  @contact = @user.contact != nil && @user.contact != ""
  @twitter = @user.twitter != nil && @user.twitter != ""
  @mail = @user.mail != nil && @user.mail != ""
end

Antworten:


196

Es gibt eine Methode, die dies für Sie erledigt:

def show
  @city = @user.city.present?
end

Die present?Methode testet auf Nicht- nilPlus hat Inhalt. Leere Zeichenfolgen, Zeichenfolgen, die aus Leerzeichen oder Tabulatoren bestehen, gelten als nicht vorhanden.

Da dieses Muster so häufig vorkommt, gibt es in ActiveRecord sogar eine Verknüpfung:

def show
  @city = @user.city?
end

Dies ist ungefähr gleichwertig.

Das Testen von vs nilist fast immer redundant. In Ruby gibt es nur zwei logisch falsche Werte: nilund false. Wenn eine Variable nicht wörtlich sein kann false, ist dies ausreichend:

if (variable)
  # ...
end

Dies ist dem Üblichen if (!variable.nil?)oder dem, if (variable != nil)was gelegentlich auftaucht, vorzuziehen . Ruby tendiert dazu, einen reduktionistischeren Ausdruck zu bevorzugen.

Ein Grund, warum Sie mit vs. vergleichen möchten, nilist, wenn Sie eine Drei-Zustands-Variable haben, die sein kann true, falseoder wenn Sie nilzwischen den letzten beiden Zuständen unterscheiden müssen.


9
Beachten Sie, dass Sie ab Ruby 2.3.0 viele redundante Nullprüfungen mit dem einsamen Operator if @user && @user.authenticatedif @user&.authenticated

1
Ein weiterer Grund , warum Sie wollen würde tun if object.present?über if object, wenn Sie das Objekt später in Dekorateur wickeln, wäre das Ergebnis ändern , wenn Sie verwendet .present?. philihp.com/2018/prefer-if-object-present-over-if-object.html
Philihp Busby

12

Sie können .present verwenden? welches in ActiveSupport enthalten ist.

@city = @user.city.present?
# etc ...

Sie könnten es sogar so schreiben

def show
  %w(city state bio contact twitter mail).each do |attr|
    instance_variable_set "@#{attr}", @user[attr].present?
  end
end

Es ist erwähnenswert, dass Sie verwenden können, wenn Sie testen möchten, ob etwas leer ist .blank?(dies ist das Gegenteil von .present?).

Auch nicht verwenden foo == nil. Verwenden Sie foo.nil?stattdessen.


@Mayank, das OP setzt eine Instanzvariable auf true/ falsevalue. reciever.present?gibt true zurück, wenn der receiverWert nicht leer ist. Weitere Erläuterungen finden Sie in den von mir verlinkten Dokumenten.
Vielen Dank, dass Sie

danke, ich habe deinen Standpunkt verstanden, aber ich kann nicht verstehen, wie instance_variable_set "@ # {attr}", @user [attr] .present? wird funktionieren..?
Neo-Code

@ Mayank, instance_variable_set("@foo", "bar")ist das gleiche wie @foo = "bar". Es ist nur eine programmatische Methode zum Festlegen von Instanzvariablen ^^
Vielen Dank

okz danke jetzt habe ich verstanden ... aber noch etwas was javascript: atob ("bmFreW90b0BnbWFpbC5jb20 ="); meint ?
Neo-Code

Mayank, führen Sie es in einer Javascript-Konsole aus, um es herauszufinden!
Vielen Dank, dass Sie
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.