Często muszę sprawdzić, czy jakaś wartość jest pusta i napisać „Brak danych” w ten sposób:
@user.address.blank? ? "We don't know user's address" : @user.address
A kiedy mamy około 20-30 pól, które musimy przetworzyć w ten sposób, robi się brzydko.
To, co zrobiłem, to rozszerzona klasa String z or
metodą
class String
def or(what)
self.strip.blank? ? what : self
end
end
@user.address.or("We don't know user's address")
Teraz wygląda lepiej. Ale nadal jest surowy i szorstki
Jak byłoby lepiej rozwiązać mój problem. Może lepiej byłoby rozszerzyć ActiveSupport class
lub użyć metody pomocniczej, mixinów lub czegokolwiek innego. Co może mi powiedzieć idealogia ruby, twoje doświadczenie i najlepsze praktyki.
ruby-on-rails
ruby
fl00r
źródło
źródło
Phrogz w pewnym sensie podsunął mi pomysł w komentarzu PofMagicfingers, ale co z zastąpieniem | zamiast?
class String def |(what) self.strip.blank? ? what : self end end @user.address | "We don't know user's address"
źródło
Ponieważ robisz to w Ruby on Rails, wygląda na to, że pracujesz z modelem. Jeśli chcesz mieć rozsądną wartość domyślną w całej aplikacji, możesz (na przykład) zastąpić
address
metodę dla swojegoUser
modelu.Nie znam ActiveRecord wystarczająco dobrze, aby zapewnić dobry kod; w Sequelu byłoby to coś takiego:
class User < Sequel::Model def address if (val=self[:address]).empty? "We don't know user's address" else val end end end
... ale w powyższym przykładzie wydaje się, że będziesz mieszał logikę widoku w swoim modelu, co nie jest dobrym pomysłem.
źródło
Twoja metoda lub może mieć niepożądane skutki uboczne, ponieważ wartość alternatywna (domyślna) jest zawsze oceniana, nawet jeśli ciąg nie jest pusty.
Na przykład
@user.address.or User.make_a_long_and_painful_SQL_query_here
dałoby dodatkową pracę, nawet jeśli adres nie jest pusty. Może mógłbyś to trochę zaktualizować (przepraszam za mylącą jedną linijkę, próbując mówić krótko):
class String def or what = "" self.strip.empty? ? block_given? ? yield : what : self end end @user.address.or "We don't know user's address" @user.address.or { User.make_a_long_and_painful_SQL_query_here }
źródło
a=2 ; a == 2 ? "ok" : @b = 3 ; @b; #=> nil
Prawdopodobnie lepiej jest rozszerzyć ActiveRecord lub poszczególne modele zamiast String.
Twoim zdaniem możesz preferować bardziej wyraźny wzór, taki jak
@user.attr_or_default :address, "We don't know the user's address"
źródło
Rubin:
unless my_str.empty? then my_str else 'default' end
RoR:
unless my_str.blank? then my_str else 'default' end
źródło