Якщо рядок порожній, поверніть якесь значення за замовчуванням


93

Часто мені потрібно перевірити, чи не пусте якесь значення, і написати так: "Немає даних" так:

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

І коли ми отримуємо близько 20-30 полів, які нам потрібно обробити таким чином, це стає потворним.

Те, що я зробив, - це розширений клас String за допомогою 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

По-перше, це переважно, оскільки в моєму рішенні я повинен розширити 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

... але для прикладу вище це здається, що ви змішали б логіку перегляду у своїй моделі, що не є гарною ідеєю.


Так, погана ідея встановлювати за замовчуванням в моделях :) Мої форми будуть плакати
fl00r

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
Він буде виконаний під час здійснення первинного дзвінка, а не за допомогою оператора. Всі аргументи будуть оцінені при виклику методу.
Тонту

2

Можливо, краще розширити ActiveRecord або окремі моделі замість рядка.

На ваш погляд, ви можете віддати перевагу більш чіткому шаблону типу

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

Це частина Active Record? Не знайшов посилань.
cabe56

0

Рубін:

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

RoR:

unless my_str.blank? then my_str else 'default' end
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.