Search code examples
ruby-on-railsrubydevise

NoMethodError: undefined method `username' for true:TrueClass


Environment

  • Ruby [2.6.6]
  • Rails [4.2.8]
  • Devise [4.7.3]

Current behavior

Hello people, I am facing issue while user is already signing and my apps perform actions successfully which are basically callbacks after login and routing to search page. Basically I am using a before_action named as :requires_auth_token which has been used in my all controllers (i.e search,message,cart,etc).

And above before action method is been stored in my base_controller below here is the snippet for same.

def requires_auth_token
    authenticate_or_request_with_http_token do |token, options|
      self.current_user_token = UserToken.find_by(
        token: token,
        installation_identifier: options[:installation_identifier]
      )
      self.installation_identifier = options[:installation_identifier]
      if session[:utoken].blank?
        user = self.current_user_token.try(:user)
        if user.present? && user.active?
          self.current_user = sign_in(:user, self.current_user_token.user)
          session[:utoken] = token
        end
      else
        if self.current_user_token
          if self.current_user_token.current_token_valid?(@org)
            self.current_user = self.current_user_token.user
          else
            sign_out(:user)
            self.current_user_token.destroy
            session[:utoken] = nil
          end
        end
      end
      set_user_context
      self.current_user.present? ? self.current_user : false
    end
  end

So here my code breaks out at :set_user_context beacause I am using HoneyBadger(Application for trace out the error if any ) for checking the errors in my app while its production.

Below is the code for :set_user_context:

def set_user_context
    Honeybadger.context(
      username: current_user.username,
      user_email: current_user.email, 
      user_id: current_user.id, 
    )  if current_user
  end

So this gives me error as NoMethodError: undefined method username for true:TrueClass

For which it seems to me this is because of this line :- https://github.com/heartcombo/devise/blob/400eaf7fbe05f50b48c08dc7dbf23259cbdb8bdb/lib/devise/controllers/sign_in_out.rb#L51

As it returns boolean true value and stored in self.current_user. Can some one here explain me why this is behaving differently is this issue with warden ?

Expected behavior

Here expected behaviour is the return user active-record object instead of true value.

Thanks in advance for helping.


Solution

  • Extending the answer provided by @jeffdill2 and your understanding.
    Yes, the method sign_in(:user, self.current_user_token.user) returns true and you are assigning it to self.current_user due to which any methods you are expecting to use on the user object would not work.

    You can update the logic as below and check if it helps:

          if session[:utoken].blank?
            user = self.current_user_token.try(:user)
            if user.present? && user.active? && sign_in(:user, user)
              self.current_user = user
              session[:utoken] = token
            end
          else
            # [...More logic]
          end