Ответ 1
ActiveSupport добавляет метод presence
ко всем объектам, которые возвращают его ресивер, если present?
(противоположность blank?
) и nil
в противном случае.
Пример:
host = config[:host].presence || 'localhost'
Часто мне нужно проверить, пусто ли какое-то значение и записать, что "Нет данных":
@user.address.blank? ? "We don't know user 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 address")
Теперь он выглядит лучше. Но он все еще сырой и грубый
Как было бы лучше решить мою проблему. Возможно, было бы лучше расширить ActiveSupport class
или использовать вспомогательный метод или микшины или что-нибудь еще. Какая рубиновая идеология, ваш опыт и лучшие практики могут мне рассказать.
ActiveSupport добавляет метод presence
ко всем объектам, которые возвращают его ресивер, если present?
(противоположность blank?
) и nil
в противном случае.
Пример:
host = config[:host].presence || 'localhost'
Phrogz вроде дал мне идею в комментарии PofMagicfingers, но как насчет переопределения | вместо этого?
class String
def |(what)
self.strip.blank? ? what : self
end
end
@user.address | "We don't know user address"
Поскольку вы делаете это в Ruby on Rails, похоже, что вы работаете с моделью. Если вы хотите получить разумное значение по умолчанию во всем своем приложении, вы можете (например) переопределить метод address
для вашей модели User
.
Я не знаю ActiveRecord достаточно хорошо, чтобы обеспечить хороший код для этого; в Sequel это будет что-то вроде:
class User < Sequel::Model
def address
if (val=self[:address]).empty?
"We don't know user address"
else
val
end
end
end
... но для примера выше это похоже на то, что вы смешаете логику представления в своей модели, что не очень хорошая идея.
У вашего метода или могут быть некоторые нежелательные побочные эффекты, так как альтернативное (по умолчанию) значение всегда оценивается, даже если строка не пуста.
Например
@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 address"
@user.address.or { User.make_a_long_and_painful_SQL_query_here }
Возможно, лучше расширить ActiveRecord или отдельные модели вместо String.
По вашему мнению, вы можете предпочесть более явный шаблон, например
@user.attr_or_default :address, "We don't know the user address"