Если строка пуста, вернуть некоторое значение по умолчанию - PullRequest
90 голосов
/ 27 января 2011

Часто мне нужно проверить, не является ли какое-то значение пустым, и написать, что «Нет данных», вот так:

@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 или использовать вспомогательный метод, или миксины, или что-то еще. Какая рубиновая идеология, ваш опыт и лучшие практики могут рассказать мне.

Ответы [ 6 ]

221 голосов
/ 27 января 2011

ActiveSupport добавляет метод presence ко всем объектам, который возвращает его получатель, если present? (противоположно blank?), и nil в противном случае.

Пример:

host = config[:host].presence || 'localhost'
12 голосов
/ 27 января 2011

Phrogz дал мне идею в комментарии PofMagicfingers, но как насчет переопределения |вместо?

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

@user.address | "We don't know user's address"
2 голосов
/ 27 января 2011

Возможно, лучше расширять ActiveRecord или отдельные модели вместо String.

По вашему мнению, вы можете предпочесть более явный шаблон, например

@user.attr_or_default :address, "We don't know the user's address"
2 голосов
/ 27 января 2011

Ваш метод или может иметь некоторые нежелательные побочные эффекты, поскольку альтернативное значение (по умолчанию) всегда оценивается, даже если строка не пустая.

Например

@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 }
2 голосов
/ 27 января 2011

Поскольку вы делаете это в Ruby on Rails, похоже, вы работаете с моделью. Если вам нужно разумное значение по умолчанию везде в вашем приложении, вы можете (например) переопределить метод address для вашей модели User.

Iнедостаточно хорошо знаете ActiveRecord, чтобы обеспечить хороший код для этого;в сиквеле это будет что-то вроде:

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

... но для приведенного выше примера кажется, что вы бы смешали логику вида с вашей моделью, что не очень хорошая идея.

0 голосов
/ 23 февраля 2019

Ruby:

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

RoR:

unless my_str.blank? then my_str else 'default' end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...