If string is empty then return some default value

Ruby on-RailsRuby

Ruby on-Rails Problem Overview


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.

Ruby on-Rails Solutions


Solution 1 - Ruby on-Rails

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 - Ruby on-Rails

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 - Ruby on-Rails

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 - Ruby on-Rails

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 }

Solution 5 - Ruby on-Rails

It is probably better to extend ActiveRecord or individual models instead of String.

In your view, you might prefer a more explicit pattern like

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

Solution 6 - Ruby on-Rails

Ruby:

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

RoR:

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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionfl00rView Question on Stackoverflow
Solution 1 - Ruby on-RailsDavid PhillipsView Answer on Stackoverflow
Solution 2 - Ruby on-RailsMatt BriggsView Answer on Stackoverflow
Solution 3 - Ruby on-RailsPhrogzView Answer on Stackoverflow
Solution 4 - Ruby on-RailsTonttuView Answer on Stackoverflow
Solution 5 - Ruby on-Railsmaxl0rdView Answer on Stackoverflow
Solution 6 - Ruby on-RailsLucioView Answer on Stackoverflow