tajihiro
tajihiro

Reputation: 2443

function nil.team_name/0 is undefined

I have two kind of query. Both use same view. One returns latest game JSON. The other returns all games.

View

  def render("game.json", %{game: game}) do
    %{id: game.id,
      season_id: game.season_id,
      game_name: game.game_name,
      home_team_id: game.home_team_id,
      home_team_name: game.home_team.team_name,
      away_team_id: game.away_team_id,
      away_team_name: game.away_team.team_name,
      comments: game.comments}
  end

It works. And returns JSON.

  def latest_game do
    query = from g in Game,
            order_by: [desc: g.game_date, desc: g.game_time],
            preload: [:away_team, :home_team]
    query
      |> first(:game_date)
      |> first(:game_time)
      |> Repo.one()
  end

But it does not work. It shows error UndefinedFunctionError at GET /api/games function nil.team_name/0 is undefined in view.

  def list_games do
    query = from g in Game,
            preload: [:away_team, :home_team]
    Repo.all(query)
  end

This is model.

defmodule Sample.Scoresheet.Game do
  use Ecto.Schema
  import Ecto.Changeset

  schema "games" do
    field :game_name, :string
    field :game_date, :date
    field :game_time, :time

    belongs_to :home_team, Sample.Scoresheet.Team
    belongs_to :away_team, Sample.Scoresheet.Team

    timestamps()
  end

Please give me some advice. Thanks.

Upvotes: 1

Views: 74

Answers (1)

Aleksei Matiushkin
Aleksei Matiushkin

Reputation: 121000

The error

UndefinedFunctionError at GET /api/games function nil.team_name/0 is undefined

means that one (or both) of the associations

belongs_to :home_team, Sample.Scoresheet.Team
belongs_to :away_team, Sample.Scoresheet.Team

is not set, and either game.home_team.team_name or game.away_team.team_name fails to get to team_name because it returns nil as a team.

One should have constraints on the database (table games) making both foreign keys to teams mandatory, that way you’ll get meaningful error messages and the data will be always consistent.

Meanwhile, I’d suggest you to check your seeds and/or how you insert games into the database and make both teams a mandatory with Ecto.Changeset.validate_required/3.

Upvotes: 3

Related Questions