【发布时间】:2021-09-11 09:11:03
【问题描述】:
首先:我有一个架构players和一个架构matches,我想在phoenix 1.6中建立它们之间的belong_to,has_many关系。我尝试过的:
defmodule TennisPhx.Matches.Match do
use Ecto.Schema
import Ecto.Changeset
alias TennisPhx.Participants.Player
schema "matches" do
has_many :first_players, Player, foreign_key: :first_player_key_id <------
has_many :second_players, Player, foreign_key: :second_player_key_id <-------
# other not relevant fields
timestamps()
end
@doc false
def changeset(match, attrs) do
match
|> cast(attrs, [:tour_id, :first_player, :second_player, :starting_datetime, :location_id, :phase_id, :status_id, :player_unit_id])
|> validate_required([:tour_id, :location_id, :phase_id, :player_unit_id])
end
end
defmodule TennisPhx.Participants.Player do
use Ecto.Schema
import Ecto.Changeset
alias TennisPhx.Events.Tour
alias TennisPhx.Matches.Match
schema "players" do
# other fields
belongs_to :first_players, Match, foreign_key: :first_player_key_id
belongs_to :second_players, Match, foreign_key: :second_player_key_id
timestamps()
end
@doc false
def changeset(player, attrs) do
player
|> cast(attrs, [:name, :nickname, :info, :birthdate])
|> validate_required([:name])
end
end
我在上下文中的“assign_match”函数:
def assign_match(%Tour{} = tour, first_player, second_player, day, month, year, location, phase, unit) do
tt = tour.id
%Match{}
|> Match.changeset(%{tour_id: tour.id, first_player: first_player, second_player: second_player, location_id: location, phase_id: phase, player_unit_id: unit})
|> Repo.insert()
end
还有迁移:
def change do
alter table("matches") do
add(:first_player, references(:players, on_delete: :delete_all))
add(:second_player, references(:players, on_delete: :delete_all))
end
end
我得到了什么错误:
unknown field `:first_player` given to cast. Either the field does not exist or it is a :through association (which are read-only). The known fields are: :first_players, :id, :inserted_at, :location, :location_id, :phase, :phase_id, :player_unit, :player_unit_id, :score, :second_players, :starting_datetime, :status, :status_id, :tour, :tour_id, :updated_at
为什么?我们可以清楚的看到迁移中的字段是first_player,单数。当将列重命名为复数时,first_players、second_players 我明白了:
[error] GenServer #PID<0.609.0> terminating
** (RuntimeError) casting assocs with cast/4 for :first_players field is not supported, use cast_assoc/3 instead
我在这里做错了什么?想不通。。
【问题讨论】:
标签: elixir ecto has-and-belongs-to-many phoenix