2

I follow this post. In my view:

- if current_user
- if current_user.present?
- if current_user.exists?
- if current_user.any?

I get the error:

undefined method `exists?' for #<User:0x00007fd68f4067b8>
undefined method `any?' for #<User:0x00007fd68f4067b8>

So only the first 2 work. Why? Is there any difference in performance of:

- if current_user
vs
- if current_user.present?

and

- if current_user.name
vs
- if current_user.name.present?
Jun Dalisay
  • 1,165
  • 2
  • 12
  • 26
  • Possible duplicate of [A concise explanation of nil v. empty v. blank in Ruby on Rails](https://stackoverflow.com/questions/885414/a-concise-explanation-of-nil-v-empty-v-blank-in-ruby-on-rails) – matthewd Aug 17 '18 at 06:50
  • The post is about collections, but you are trying to check it on the instance - not a good idea. – Vasilisa Aug 17 '18 at 06:57

3 Answers3

6

When you call methods on objects you have to know what you are doing.

current_user.present?

Here you call a method called present? on the object current_user. This works because method present? is defined on this object. When you do

current_user.exists?

you expect current_user to respond to a method called exists?. But it does not, thus error.

You mixed up a few things into this single question.

Only call methods on an object if you are sure it responds to this method.

Difference between if current_user vs if current_user.present? is implicit vs explicit check for object truthiness. See, in Ruby, everything except for false and nil is truthy. So if current_user means if current_user is anything except for nil or false then proceed. You rely on expression evaluation, while in current_user.present? you rely explicitly on a return value from a method call (present?).

I suggest you

  • always go with explicit because it reads better;
  • read about objects and methods in Ruby.
Andrey Deineko
  • 51,333
  • 10
  • 112
  • 145
  • From my understanding, nil? blank? present? apply to everything and exists? any? empty? apply to records. But doesn't current_user of Devise return a User record, just as @user returns a record? – Jun Dalisay Aug 17 '18 at 07:29
  • @JunDalisay to check whether an object respond to a method you can do `your_object.respond_to?(:method_name)`. – Andrey Deineko Aug 17 '18 at 07:30
0

current_user returns the current user if the current user is present. So it could return nil.

nil.present? will evaluate to false <User:0x00007fd68f4067b8>#present? will evaluate to true

Neither of these is significantly less performant than the other

any? doesn't work because user is not Enumerable

exists? doesn't work because the User class doesn't have a method called exists? You could be thinking of the class method which checks if a given record exists.

using current_user.name runs the risk of calling nil.name when there is no user. Your best bet is to use current_user or current_user.present?

Tyrone Wilson
  • 4,328
  • 2
  • 31
  • 35
-1

For condition checking both are same. current_user will return user object or nil and cuurent_user.present? will return boolean.

I would suggest to use current_user not the current_user.present?.