blank? and present?: the two cases that surprise everyone
A fallback pattern in one line
app/models/identity/user.rb, this app's model:
name.presence || username
That gives a user's display name if they set one, and their username otherwise. presence (not present?) returns self when the receiver counts as present and nil when it doesn't, so it chains with || directly. There's no if/else, and no boolean that gets read once and thrown away. It's ActiveSupport's extension of Object, and it works on strings, arrays, hashes, nil, booleans and numbers alike, all checked in this lesson.
The full truth table, run in this app
nil.blank? # => true
"".blank? # => true
" ".blank? # => true
"x".blank? # => false
0.blank? # => false
1.blank? # => false
false.blank? # => true
true.blank? # => false
[].blank? # => true
[1].blank? # => false
{}.blank? # => true
{a: 1}.blank? # => false
Those are twelve calls, run in this app's console. present? is !blank? for every one of them: ActiveSupport's source defines it that way, one method returning the other's negation.
The two cases that catch people
0.blank? is false, and that's a common source of bugs. A number zero counts as present, not missing, and so does the string "0" a form submits. Code that means "was a quantity given at all" and uses .blank? to catch a deliberate zero gets surprised the moment a user enters 0.
false.blank? is true, the other direction. A boolean field set to false on purpose, such as active: false or visible: false, reads as blank to this method, just as if it had never been set. blank?'s job is "would this be useless to display or process", not "is this falsy" or "is this missing from the params hash". false fails that first test even though it's a valid, meaningful value.
What this course covers
Seven lessons, each checked against this app's code or Rails' installed source. This lesson covers blank?, present? and presence, with the truth table and its two surprising cases. Lesson 2 covers Time.current versus Time.now, which differ by hours on the machine that ran these examples. Lesson 3 covers ActiveSupport::Duration, the object behind .days, .hours and .ago, which isn't a disguised integer. Lesson 4 covers beginning_of_day, beginning_of_week and beginning_of_month, chained onto .ago in this app's richest reporting query. Lesson 5 covers to_sentence, which turns an array of errors into readable prose with its own punctuation rule. Lesson 6 covers try, and a correction about which of except and except! still belongs to ActiveSupport today.
Keep going with lesson 2
Time.current vs Time.now, different on the machine that ran them
Why Time.current and Time.now differ by hours, and how Rails defaults Time.zone to UTC.
A free account also gives you the quizzes, your progress and notes, and the discussion.