文字列が空の場合、デフォルト値を返します


93

多くの場合、一部の値が空白であるかどうかを確認し、そのような「データがありません」と書く必要があります。

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

そして、この方法で処理する必要のある20〜30のフィールドを取得すると、醜くなります。

私が作ったのはorメソッドを持つ拡張された文字列クラスです

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

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

今では良く見えています。しかし、それはまだ生で荒いです

私の問題を解決する方が良いでしょう。ActiveSupport classヘルパーメソッドやミックスインなどを拡張または使用する方がよいでしょう。ルビーのアイデア、あなたの経験、ベストプラクティスが私に教えてくれるものは何ですか。

回答:


227

ActiveSupportは、presenceすべてのオブジェクトにメソッドを追加しますpresent?(その逆の場合blank?)、nilそれ以外の場合はレシーバーを返します。

例:

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

2
これはカッコいい。デフォルトのレールの可能性が優先されます。ありがとう!
fl00r 2011年

第一に、私のソリューションでは少なくともString、Fixnum、およびNilClassを拡張する必要があるため、それが優先されます。そして、ここでは、バイクルなしで明確なコードを使用することができます
fl00r

12

PhrogzはPofMagicfingersのコメントで私にアイデアを与えましたが、オーバーライドについてはどうですか?代わりに?

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

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

2

Ruby on Railsでこれを行っているので、モデルで作業しているように見えます。場合あなたは、合理的なデフォルト値を望んでいたどこでもあなたのアプリで、あなたは(たとえば)オーバーライドすることができますaddressあなたのための方法Userのモデルを。

このための適切なコードを提供するのに十分なほどActiveRecordを知りません。続編では次のようになります。

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

...しかし、上の例の場合、ビューロジックをモデルに混在させるように思えますが、これは良い考えではありません。


はい、モデルにデフォルトを設定することはお
勧めできません

2

あなたまたは代替(デフォルト)値は常に文字列が空でない場合でも、評価されるための方法は、いくつかの望ましくない副作用があるかもしれません。

例えば

@user.address.or User.make_a_long_and_painful_SQL_query_here

アドレスが空でない場合でも余分な作業を行います。多分あなたはそれを少し更新することができます(ワンライナーを混乱させて、それを短くしようとすることについて申し訳ありません):

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 }

良い発言。とった。しかし、なぜすべてのコードが実行されるのでしょうか?見て:a=2 ; a == 2 ? "ok" : @b = 3 ; @b; #=> nil
fl00r

2
三項演算子ではなく、元の呼び出しを行うときに実行されます。すべての引数はメソッド呼び出しで評価されます。
Tonttu、2011年

2

Stringではなく、ActiveRecordまたは個々のモデルを拡張することをお勧めします。

あなたの見解では、あなたはより明確なパターンを好むかもしれません

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

これはActive Recordの一部ですか?参照は見つかりませんでした。
cabe56 2013

0

ルビー:

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

RoR:

unless my_str.blank? then my_str else 'default' end
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.