无法在Phoenix / Ecto中使用belongs_to关联进行播种

时间:2019-04-20 08:12:14

标签: elixir ecto phoenix

我有一个TeamGame表,如下所示:

schema "teams" do
    field :name, :string
    has_many :games, LvdnApi.Fixtures.Game
    timestamps()
  end

  schema "games" do
    field :away_team_score, :integer
    field :competition, :string
    field :game_datetime, :utc_datetime
    field :home_team_score, :integer
    field :round, :string
    belongs_to :home_team, LvdnApi.Fixtures.Team
    belongs_to :away_team, LvdnApi.Fixtures.Team
    timestamps()
  end

  @doc false
  def changeset(game, attrs) do
    game
    |> cast(attrs, [:home_team_score, :away_team_score, :competition, :round, :game_datetime, :home_team, :away_team])
    |> validate_required([:competition, :round, :game_datetime, :home_team, :away_team])
    |> assoc_constraint(:home_team)
    |> assoc_constraint(:away_team)
  end

我想要种子数据,所以我在seeds.ex中写了这个:

alias LvdnApi.Repo
alias LvdnApi.Fixtures.Team
alias LvdnApi.Fixtures.Game

%Team{name: "Olympique Lyonnais"} |> Repo.insert!
%Team{name: "Stade de Reims"} |> Repo.insert!
%Team{name: "Lille OSC"} |> Repo.insert!

%Game{
  home_team: 1,
  away_team: 2,
  home_team_score: 2,
  away_team_score: 2,
  competition: "Ligue 1",
  round: "14ème journée",
  game_datetime: %DateTime{
    year: 2018,
    month: 11,
    day: 24,
    zone_abbr: "CET",
    hour: 20,
    minute: 0,
    second: 0,
    microsecond: {0, 0},
    utc_offset: 3600,
    std_offset: 0,
    time_zone: "Etc/UTC"
  }
}
|> Repo.insert!

%Game{
  home_team: 3,
  away_team: 1,
  competition: "Ligue 1",
  round: "35ème journée",
  game_datetime: %DateTime{
    year: 2019,
    month: 5,
    day: 5,
    zone_abbr: "CET",
    hour: 21,
    minute: 0,
    second: 0,
    microsecond: {0, 0},
    utc_offset: 3600,
    std_offset: 0,
    time_zone: "Etc/UTC"
  }
}
|> Repo.insert!

对于我的Team来说,它工作正常,但对于我的Game s,却出现了此错误:

* (Ecto.InvalidChangesetError) could not perform insert because changeset is invalid.

Errors

    %{away_team: [{"is invalid", [type: :map]}]}

Applied changes

    %{
      away_team_score: 2,
      competition: "Ligue 1",
      game_datetime: #DateTime<2018-11-24 20:00:00+01:00 CET Etc/UTC>,
      home_team_score: 2,
      round: "14ème journée"
    }

Params

    nil

Changeset

    #Ecto.Changeset<
      action: :insert,
      changes: %{
        away_team_score: 2,
        competition: "Ligue 1",
        game_datetime: #DateTime<2018-11-24 20:00:00+01:00 CET Etc/UTC>,
        home_team_score: 2,
        round: "14ème journée"
      },
      errors: [away_team: {"is invalid", [type: :map]}],
      data: #LvdnApi.Fixtures.Game<>,
      valid?: false
    >

    (ecto) lib/ecto/repo/schema.ex:169: Ecto.Repo.Schema.insert!/4
    priv/repo/seeds.exs:42: (file)
    (elixir) lib/code.ex:767: Code.require_file/2
    (mix) lib/mix/tasks/run.ex:147: Mix.Tasks.Run.run/5
    (mix) lib/mix/tasks/run.ex:86: Mix.Tasks.Run.run/1
    (mix) lib/mix/task.ex:331: Mix.Task.run_task/3
    (mix) lib/mix/task.ex:365: Mix.Task.run_alias/3
    (mix) lib/mix/task.ex:292: Mix.Task.run/2
    (mix) lib/mix/task.ex:365: Mix.Task.run_alias/3
    (mix) lib/mix/task.ex:292: Mix.Task.run/2
    (mix) lib/mix/cli.ex:79: Mix.CLI.run_task/2
    (elixir) lib/code.ex:767: Code.require_file/2

我应该如何编写Game结构,以便以正确的方式创建它们?

1 个答案:

答案 0 :(得分:0)

发现,当我在seed.ex中创建游戏时,我只需要将home_teamaway_team更改为home_team_idaway_team_id

%Game{
  home_team_id: 1,
  away_team_id: 2,
  home_team_score: 2,
  away_team_score: 2,
  competition: "Ligue 1",
  round: "14ème journée",
  game_datetime: %DateTime{
    year: 2018,
    month: 11,
    day: 24,
    zone_abbr: "CET",
    hour: 20,
    minute: 0,
    second: 0,
    microsecond: {0, 0},
    utc_offset: 3600,
    std_offset: 0,
    time_zone: "Etc/UTC"
  }
}
|> Repo.insert!