If string is empty then return some default value
Often I need to check if some value is blank and write that "No data present" like that:
@user.address.blank? ? "We don't know user's address" : @user.address
And when we have got about 20-30 fields that we need to process this way it becomes ugly.
What I've made is extended String class with or
method
class String
def or(what)
self.strip.blank? ? what : self
end
end
@user.address.or("We don't know user's address")
Now it is looking better. But it is still raw and rough
How it would be better to solve my problem. Maybe it would be better to extend ActiveSupport class
or use helper method or mixins or anything else. What ruby idealogy, your experience and best practices can tell to me.
Solution 1:
ActiveSupport adds a presence
method to all objects that returns its receiver if present?
(the opposite of blank?
), and nil
otherwise.
Example:
host = config[:host].presence || 'localhost'
Solution 2:
Phrogz sort of gave me the idea in PofMagicfingers comment, but what about overriding | instead?
class String
def |(what)
self.strip.blank? ? what : self
end
end
@user.address | "We don't know user's address"
Solution 3:
Since you're doing this in Ruby on Rails, it looks like you're working with a model. If you wanted a reasonable default value everywhere in your app, you could (for example) override the address
method for your User
model.
I don't know ActiveRecord well enough to provide good code for this; in Sequel it would be something like:
class User < Sequel::Model
def address
if (val=self[:address]).empty?
"We don't know user's address"
else
val
end
end
end
...but for the example above this seems like you'd be mixing view logic into your model, which is not a good idea.
Solution 4:
Your or method might have some unwanted side-effects, since the alternative (default) value is always evaluated, even if the string is not empty.
For example
@user.address.or User.make_a_long_and_painful_SQL_query_here
would make extra work even if address is not empty. Maybe you could update that a bit (sorry about confusing one-liner, trying to keep it short):
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 }