The usual FunctionClauseError - phoenix

Hello again from me :slight_smile:

Receiving an ** (FunctionClauseError) no function clause matching in TennisPhx.Matches.get_match_by_players/2 error from

 def get_match_by_players(%Player{} = first_player, %Player{} = second_player) do
    first_player_id = first_player.id
    second_player_id = second_player.id
    query = from(m in Match, where: m.first_player_id == ^first_player_id and m.second_player_id == ^second_player_id)
    Repo.all(query)
  end

%Player is alias correctly, when doing IO.inspect on first_player & second_player I receive a player struct, as it has to be. Example:

MESSAGE===>: [
%TennisPhx.Participants.Player{
__meta__: #Ecto.Schema.Metadata<:loaded, "players">,
birthdate: ~N[1940-07-01 00:00:00],
hand: "left-handed",
id: 1,
info: "rk",
inserted_at: ~N[2021-09-04 14:09:52],
name: "RK",
nickname: "rk",
points: 6,
updated_at: ~N[2021-12-06 15:31:00]
}
]

When trying to pass only one player - def get_match_by_players(%Player{} = first_player) do the FunctionClause error stays. For me the syntax is correct, isnt it?

Doing the exact same thing with different struct works: def toggle_tour_players(%Tour{} = tour, player_id) do, where tour:

MESSAGE===>: %TennisPhx.Events.Tour{
__meta__: #Ecto.Schema.Metadata<:loaded, "tours">,
date: ~N[2023-01-01 00:00:00],
id: 1,
info: "info",
inserted_at: ~N[2021-09-04 14:09:25],
location: #Ecto.Association.NotLoaded<association :location is not loaded>,
location_id: 1,
}

What im doing wrong?

1 Like

Can you post the full error message with stacktraces and the related lines in the source code?

3 Likes

hi @ykostov ! Neat, a tennis app! :heart:

Do you mind sharing a stack trace of the error if you can?

Edit: what @josevalim asked :laughing: , he is too fast.

The problem was that I was trying to pass list of Player Struct instead of Struct. I was trying to get from a <.form string (:name for player, autocomplete input) instead of id, then queryed to get a list, but obviously it is a bad idea. A dropdown with value of id is better and the solution of my question:

<%= select(f, :player1_id, Enum.map(@players, &{&1.name, &1.id}), prompt: [key: "Choose player1"]%>

However, thanks for the responses :slight_smile:

Yeah, table tennis actually :wink:

1 Like