Marsel.V
Marsel.V

Reputation: 1044

has multiple clauses and defines defaults in one or more clauses

I have a function confirm_user, which can be called with the argument %User{} or nil.

def confirm_user(%User{} = user, attrs \\ %{}) do
    Repo.update(User.confirm_changeset(user, attrs))
end

def confirm_user(nil, attrs \\ %{}) do
    {:error, :not_found}
end

But with this definition I get an error:

def confirm_user/2 has multiple clauses and defines defaults in one or more clauses

why? Is %User{} = user and nil not pattern matching?

Upvotes: 1

Views: 503

Answers (1)

PatNowak
PatNowak

Reputation: 5812

You should declare above all one head that sets default arguments:

def confirm_user(_user, attr \\ %{})
def confirm_user(%User{} = user, attrs) do
  user
  |> User.confirm_changeset(attrs)
  |> Repo.update() 
end

def confirm_user(nil, attrs) do
  {:error, :not_found}
end

You could also use a bit more explicit approach and declare confirm_user/1 on your own - this is what actually the \\ operator is doing.

def confirm_user(user) do
  confirm_user(user, %{}) # call confirm_user/2 when no attrs are provided
end

def confirm_user(%User{} = user, attrs) do
  user
  |> User.confirm_changeset(attrs)
  |> Repo.update() 
end

def confirm_user(nil, attrs) do
  {:error, :not_found}
end

%User{} = user help you to get the whole struct as the user thanks to the pattern matching, so you don't need to assign in the function block.

Edit:

Here's the exact comment with explanation how your code should looks like.

Upvotes: 4

Related Questions