Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Problems with Pipe Authenticated Routes and current_user compile-time type is (User | Nil) #1030

Closed
westonganger opened this issue Jan 10, 2019 · 3 comments

Comments

Projects
None yet
4 participants
@westonganger
Copy link
Contributor

commented Jan 10, 2019

I am using the basic authenticate pipe. I cant seem to get around errors similar to the following on authenticated actions.

undefined method 'fetch_items' for Nil (compile-time type is (User | Nil))

      items = current_user.fetch_items

Since this is an authenticated action it should be assured to be not nil. However regardless even if I try to do the following it still gives the same error.

if !current_user.nil?
  items = current_user.fetch_items
end

How can I deal with this?

@westonganger

This comment has been minimized.

Copy link
Contributor Author

commented Jan 10, 2019

Looks like I fixed it with some changes to the methods in ApplicationController.

Current Instructions:

class ApplicationController < AmberController::Base

  def current_user : User
    context.current_user
  end

  def signed_in?
    current_user ? true : false
  end

end

My working solution:

class ApplicationController < AmberController::Base

  def current_user : User
    context.current_user || User.new
  end

  def current_user?
    context.current_user
  end

  def signed_in?
    current_user? ? true : false
  end

end

Maybe the solution in the docs could be updated to this. What do you think?

@drujensen

This comment has been minimized.

Copy link
Member

commented Jan 10, 2019

Hi @westonganger This is a common error you will hit using Crystal when dealing with union types.

The union type (User | Nil) needs to be changed into User so you don't get the error. User has the method fetch_items but Nil does not, so it throws the error.

There are several ways to do this. The one that is recommended:

if user = current_user
  user.fetch_items
else
  # handle Nil type
end

The assignment will remove the Nil from the union and return only a User.

Another option is to use not_nil! if you know for sure that there is no way that it can be Nil. It's ugly on purpose:

current_user.not_nil!.fetch_items

In Crystal, you are forced to deal with the Nil case. This prevents runtime errors that are so common in Ruby.

@westonganger

This comment has been minimized.

Copy link
Contributor Author

commented Jan 10, 2019

Perfect thanks for the tips.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.