johnsona johnsona - 3 months ago 7
Ruby Question

variable assigned in conditional is used in same conditional, throws error

I'm trying to do something like this:

if user = User.find_by(email: 'example@example.com') && !user.activated?
# do something
end


but I get an error thrown saying "no method 'activated' for nil:NilClass"

Is there a way for me to accomplish this functionality without using a nested conditional?

Answer

You can use the control flow operator and over the logical operator && like so:

  if user = User.find_by(email: 'example@example.com') and !user.activated?
    # do something
  end

Example:

if a = 12 && a.even? 
  "Working"
end 
#=> undefined method `even?' for nil:NilClass
if b = 12 and b.even? 
  "Working"
end 
#=> "Working"

This works because and has a lower precedent than assignment so the assignment will occur prior to the second conditional check.

As long as you don't mind the found = in conditional, should be == warnings.

Second Option:

Your other option is explicit parentheses ie.

if a = 12 && a.even? 
  "Working"
end 
#=> undefined method `even?' for nil:NilClass
if (b = 1) && b.even? 
  "Working"
end 
#=> "Working"

This works because the parentheses () will be evaluated first before the conditional is evaluated so the assignment will occur inside the parens and then be evaluated as part of the conditional.

More on Ruby Operator Precedence

Comments