我有一个Team
和Game
表,如下所示:
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结构,以便以正确的方式创建它们?
答案 0 :(得分:0)
发现,当我在seed.ex中创建游戏时,我只需要将home_team
和away_team
更改为home_team_id
和away_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!