Dize boşsa, bazı varsayılan değerleri döndürün


94

Genellikle bir değerin boş olup olmadığını kontrol etmem ve şöyle "Veri yok" yazmam gerekir:

@user.address.blank? ? "We don't know user's address" : @user.address

Ve bu şekilde işlememiz gereken yaklaşık 20-30 alanımız olduğunda, işler çirkinleşiyor.

Yaptığım şey, oryöntemle genişletilmiş String sınıfı

class String
  def or(what)
    self.strip.blank? ? what : self
  end
end

@user.address.or("We don't know user's address")

Şimdi daha iyi görünüyor. Ama hala çiğ ve sert

Sorunumu çözmek nasıl daha iyi olurdu. Belki ActiveSupport classyardımcı yöntem veya karışımları veya başka herhangi bir şeyi genişletmek veya kullanmak daha iyi olur . Ruby idealojisi, deneyiminiz ve en iyi uygulamalarınız bana ne söyleyebilir.

Yanıtlar:


232

ActiveSupport presence, tüm nesnelere, eğer present?(tersi blank?) ve nilaksi halde alıcısını döndüren bir yöntem ekler .

Misal:

host = config[:host].presence || 'localhost'

2
bu havalı. Varsayılan ray olanakları tercih edilir. Thanx!
fl00r

Öncelikle tercih ediliyor çünkü benim çözümümde en azından String, Fixnum ve NilClass'ı genişletmeliyim. Ve burada bycles olmadan temiz kod kullanabilirim
fl00r

12

Phrogz, PofMagicfingers'ın yorumunda bana fikir verdi, peki ya geçersiz kılmak | yerine?

class String
  def |(what)
    self.strip.blank? ? what : self
  end
end

@user.address | "We don't know user's address"

2

Bunu Ruby on Rails'de yaptığınız için, bir model üzerinde çalışıyormuşsunuz gibi görünüyor. Eğer makul bir varsayılan değer istedik her yerde uygulamanızda, (örneğin) geçersiz olabilir addresssizin için yöntem Usermodeli.

ActiveRecord'u bunun için iyi bir kod sağlayacak kadar iyi bilmiyorum; Sequel'de şöyle bir şey olurdu:

class User < Sequel::Model
  def address        
    if (val=self[:address]).empty?
      "We don't know user's address"
    else
      val
    end
  end
end

... ancak yukarıdaki örnek için bu, görünüm mantığını modelinize karıştırıyormuşsunuz gibi görünüyor, ki bu iyi bir fikir değil.


Evet, modellerde varsayılan ayarlamak kötü bir fikir :) Formlarım ağlayacak
fl00r

2

Kişisel veya alternatif (varsayılan) değeri her zaman değerlendirilir beri yöntem dizesi boş olmasa bile, bazı istenmeyen yan etkileri olabilir.

Örneğin

@user.address.or User.make_a_long_and_painful_SQL_query_here

adres boş olmasa bile fazladan iş yapar. Belki bunu biraz güncelleyebilirsiniz (tek satırlık kafa karıştırıcı, kısa tutmaya çalıştığım için üzgünüm):

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 }

güzel sözler. Anladım. Ama neden tüm kod çalıştırılacak? görünüm:a=2 ; a == 2 ? "ok" : @b = 3 ; @b; #=> nil
fl00r

2
Üçlü operatörle değil, orijinal arama yapılırken yürütülecektir. Tüm bağımsız değişkenler yöntem çağrısında değerlendirilecektir.
Tonttu

1

ActiveRecord'u veya tek tek modelleri String yerine genişletmek muhtemelen daha iyidir.

Size göre daha açık bir model tercih edebilirsiniz.

@user.attr_or_default :address, "We don't know the user's address"

Bu Active Record'un bir parçası mı? Herhangi bir referans bulunamadı.
cabe56

0

Yakut:

unless my_str.empty? then my_str else 'default' end

RoR:

unless my_str.blank? then my_str else 'default' end
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.