Jika string kosong maka kembalikan beberapa nilai default

93

Seringkali saya perlu memeriksa apakah beberapa nilai kosong dan menulis bahwa "Tidak ada data" seperti itu:

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

Dan ketika kita memiliki sekitar 20-30 bidang yang perlu kita proses dengan cara ini, itu menjadi jelek.

Apa yang saya buat adalah kelas String diperpanjang dengan ormetode

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

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

Sekarang sudah terlihat lebih baik. Tapi masih mentah dan kasar

Bagaimana akan lebih baik untuk menyelesaikan masalah saya. Mungkin akan lebih baik untuk memperpanjang ActiveSupport classatau menggunakan metode pembantu atau mixin atau yang lainnya. Apa yang idealogi, pengalaman, dan praktik terbaik Anda dapat memberitahu saya.

fl00r
sumber

Jawaban:

227

ActiveSupport menambahkan presencemetode ke semua objek yang mengembalikan penerima jika present?(kebalikan dari blank?), dan nilsebaliknya.

Contoh:

host = config[:host].presence || 'localhost'
David Phillips
sumber
2
ini keren. Kemungkinan rel default lebih diutamakan. Terima kasih!
fl00r
Pertama, ini lebih disukai karena dalam solusi saya, saya harus memperluas setidaknya String, Fixnum, dan NilClass. Dan di sini saya bisa menggunakan kode yang jelas tanpa bycles
fl00r
12

Phrogz memberi saya ide di komentar PofMagicfingers, tapi bagaimana dengan menimpa | sebagai gantinya?

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

@user.address | "We don't know user's address"
Matt Briggs
sumber
2

Karena Anda melakukan ini di Ruby on Rails, sepertinya Anda sedang mengerjakan sebuah model. Jika Anda menginginkan nilai default yang wajar di mana pun di aplikasi Anda, Anda dapat (misalnya) mengganti addressmetode untuk Usermodel Anda .

Saya tidak tahu ActiveRecord cukup baik untuk memberikan kode yang baik untuk ini; di Sekuelnya akan menjadi seperti ini:

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

... tetapi untuk contoh di atas, ini sepertinya Anda akan mencampurkan logika tampilan ke dalam model Anda, yang sebenarnya bukan ide yang bagus.

Phrogz
sumber
Ya, adalah ide yang buruk untuk menyetel default dalam model :) Formulir saya akan menangis
fl00r
2

Metode atau Anda mungkin memiliki beberapa efek samping yang tidak diinginkan, karena nilai alternatif (default) selalu dievaluasi, meskipun string tidak kosong.

Sebagai contoh

@user.address.or User.make_a_long_and_painful_SQL_query_here

akan membuat pekerjaan ekstra bahkan jika alamat tidak kosong. Mungkin Anda bisa memperbaruinya sedikit (maaf karena satu baris membingungkan, mencoba membuatnya tetap pendek):

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 }
Tonttu
sumber
ucapan yang bagus. Mengerti. Tetapi mengapa semua kode akan dieksekusi? lihat:a=2 ; a == 2 ? "ok" : @b = 3 ; @b; #=> nil
fl00r
2
Ini akan dijalankan saat melakukan panggilan asli, bukan dengan operator terner. Semua argumen akan dievaluasi pada pemanggilan metode.
Tonttu
2

Mungkin lebih baik untuk memperluas ActiveRecord atau model individu daripada String.

Dalam pandangan Anda, Anda mungkin lebih menyukai pola yang lebih eksplisit seperti

@user.attr_or_default :address, "We don't know the user's address"
maxl0rd
sumber
Apakah ini bagian dari Rekaman Aktif? Tidak menemukan referensi apapun.
cabe56
0

Rubi:

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

RoR:

unless my_str.blank? then my_str else 'default' end
Lucio
sumber