Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a benefit to Rails' ".present?" method?

In Ruby on Rails, is there a difference between:

if obj
  # ...
end

and:

if obj.present?
  # ...
end

It seems they do the same thing and not using .present? would help keep the line of code shorter and potentially cleaner. I understand that .present? is the opposite of blank? but should we always be using it when trying to determine if an object is "truthy" or not?

Is there a performance difference of some kind?

like image 886
ardavis Avatar asked Aug 06 '19 14:08

ardavis


3 Answers

The #present? method does a bit more in that it also returns false if the string was a real but empty string (i.e. "")

Which is useful as your forms might return empty strings instead of nils.

You can also use #presence which is a useful way of returning the value only if the value is #present?

name = params[:name].presence || 'ardavis'

The above wouldn't work if params[:name] was an empty string and you didn't use #presence

like image 129
SteveTurczyn Avatar answered Nov 10 '22 15:11

SteveTurczyn


They don't do the same thing at all.

In Ruby everything except nil and false are truthy. This is amazingly sane compared to the type casting schenigans in other popular dynamic languages.

irb(main):003:0> !!""
(irb):3: warning: string literal in condition
=> true
irb(main):004:0> !!0
=> true
irb(main):005:0> !![]
=> true
irb(main):006:0> !!{}
=> true
irb(main):007:0> !!Object.new
=> true
irb(main):008:0> !!nil
=> false
irb(main):009:0> !!false
=> false

present? and presence are a part of ActiveSupport which can be used to test for nil and false but are actually more useful when dealing with user input:

irb(main):010:0> "".present?
=> false
irb(main):011:0> [].present?
=> false
irb(main):012:0> {}.present?
=> false

present? and presence are widely overused by Rails beginners that don't bother to learn Ruby first. Just use implicit truth checks (if foo) or foo.nil? if you just want to check if an argument is sent or not or if a variable is set.

And while .present? can be used on ActiveRecord collections but there are more idiomatically correct choices such as any? and none?.

like image 6
max Avatar answered Nov 10 '22 14:11

max


If you are working with string only checking if the attribute or object exists will return true, but present method will return false.

Here are some examples:

# Double negation return the boolean value
!!""
=> true


"".present?
=> false

" ".present?
=> false

[].present?
=> false

nil.present?
=> false

true.present?
=> true

false.present?
=> false

{}.present?
=> false

person = {:firstName => "John", :lastName => "Doe"}
person.present?
=> true

5.present?
=> true
like image 1
Júlio Campos Avatar answered Nov 10 '22 13:11

Júlio Campos