Ecto 当我有一个主键并且它有一个值时,为什么EXTO会引发EXTO.NoPrimaryKeyValueError?

Ecto 当我有一个主键并且它有一个值时,为什么EXTO会引发EXTO.NoPrimaryKeyValueError?,ecto,Ecto,每当我运行此代码时: {:ok, act_1} = %Kempelen.Models.GameAct{} |> Kempelen.Models.GameAct.changeset(%{ game_play: place_road, game_player: player_1, game_round: round_1 }) |> Kempelen.Database.Repo.insert 我得到一个例外: ** (Ecto.NoPr

每当我运行此代码时:

{:ok, act_1} = %Kempelen.Models.GameAct{}
  |> Kempelen.Models.GameAct.changeset(%{
      game_play: place_road,
      game_player: player_1,
      game_round: round_1
    })
  |> Kempelen.Database.Repo.insert
我得到一个例外:

** (Ecto.NoPrimaryKeyValueError) struct `%Kempelen.Models.GamePlayer{__meta__: #Ecto.Schema.Metadata<:loaded, "game_players">, account: %Kempelen.Models.Account{__meta__: #Ecto.Schema.Metadata<:loaded, "accounts">, email: "kurtis@difference-engineers.org", game_players: #Ecto.Association.NotLoaded<association :game_players is not loaded>, game_rounds: #Ecto.Association.NotLoaded<association :game_rounds is not loaded>, game_tables: #Ecto.Association.NotLoaded<association :game_tables is not loaded>, id: "65880220-e39b-450d-ba7f-0642bea8dbc8", inserted_at: ~N[2020-02-16 16:15:33], name: nil, onboarding_state: "converted", organization_memberships: #Ecto.Association.NotLoaded<association :organization_memberships is not loaded>, organizations: #Ecto.Association.NotLoaded<association :organizations is not loaded>, password: nil, password_hash: nil, role_state: "user", unconfirmed_email: "kurtis@difference-engineers.org", updated_at: ~N[2020-02-16 16:15:33], username: nil}, account_id: "65880220-e39b-450d-ba7f-0642bea8dbc8", game_acts: #Ecto.Association.NotLoaded<association :game_acts is not loaded>, game_robot: nil, game_robot_id: nil, game_table: %Kempelen.Models.GameTable{__meta__: #Ecto.Schema.Metadata<:loaded, "game_tables">, game: %Kempelen.Models.Game{__meta__: #Ecto.Schema.Metadata<:loaded, "games">, game_plays: #Ecto.Association.NotLoaded<association :game_plays is not loaded>, game_tables: #Ecto.Association.NotLoaded<association :game_tables is not loaded>, id: "31eee3b8-b43c-411a-8528-479269c63d2d", inserted_at: ~N[2020-02-16 16:15:33], name: "Settlers of Catan", organization: %Kempelen.Models.Organization{__meta__: #Ecto.Schema.Metadata<:loaded, "organizations">, accounts: #Ecto.Association.NotLoaded<association :accounts is not loaded>, games: #Ecto.Association.NotLoaded<association :games is not loaded>, id: "3311c337-f480-4292-9582-c45f249730b2", inserted_at: ~N[2020-02-16 16:15:32], name: "Hasbro", organization_memberships: #Ecto.Association.NotLoaded<association :organization_memberships is not loaded>, robots: #Ecto.Association.NotLoaded<association :robots is not loaded>, slug: "hasbro", updated_at: ~N[2020-02-16 16:15:32]}, organization_id: "3311c337-f480-4292-9582-c45f249730b2", slug: "settlers-of-catan", updated_at: ~N[2020-02-16 16:15:33]}, game_id: "31eee3b8-b43c-411a-8528-479269c63d2d", game_players: #Ecto.Association.NotLoaded<association :game_players is not loaded>, game_rounds: #Ecto.Association.NotLoaded<association :game_rounds is not loaded>, id: "2cda5e3c-c57d-4117-a541-0c6a409984b6", inserted_at: ~N[2020-02-16 16:15:33], name: "FFA", slug: "ffa", updated_at: ~N[2020-02-16 16:15:33]}, game_table_id: "2cda5e3c-c57d-4117-a541-0c6a409984b6", host: true, id: "591227e6-3ea0-4f3f-8a44-471d7073c2df", inserted_at: ~N[2020-02-16 16:15:33], name: "Kurtis", slug: "kurtis", updated_at: ~N[2020-02-16 16:15:33]}` is missing primary key value
这不仅仅是游戏模式,它也发生在游戏玩家身上

变更集似乎也认为它是有效的:

#Ecto.Changeset<
  action: nil,
  changes: %{
    game_play: #Ecto.Changeset<action: :update, changes: %{}, errors: [],
     data: #Kempelen.Models.GamePlay<>, valid?: true>,
    game_player: #Ecto.Changeset<action: :update, changes: %{}, errors: [],
     data: #Kempelen.Models.GamePlayer<>, valid?: true>,
    game_round: #Ecto.Changeset<action: :update, changes: %{}, errors: [],
     data: #Kempelen.Models.GameRound<>, valid?: true>
  },
  errors: [],
  data: #Kempelen.Models.GameAct<>,
  valid?: true
>
#exto.Changeset<
行动:无,
变化:%{
游戏玩法:#异位改变集,
游戏玩家:#异位改变集,
游戏回合:#外部变更集
},
错误:[],
数据:#Kempelen.Models.GameAct,
有效?:正确
>

好吧,我终于明白了。结果表明,虽然我希望
帐户
游戏机器人
关系是可选的(在业务逻辑中是一种或另一种),但模式中
主键:true
选项属于
,这意味着外键列必须有一个值

defmodule Kempelen.Models.GamePlayer do
  use Ecto.Schema
  import Ecto.Changeset

  @primary_key {:id, :binary_id, autogenerate: true}
  @foreign_key_type :binary_id
  schema "game_players" do
    field :name, :string
    field :slug, Kempelen.Slugs.Name.Type
    field :host, :boolean, default: false
    belongs_to :game_table, Kempelen.Models.GameTable, primary_key: true
    belongs_to :account, Kempelen.Models.Account, primary_key: true
    belongs_to :game_robot, Kempelen.Models.GameRobot, primary_key: true
    has_many :game_acts, Kempelen.Models.GameAct

    timestamps()
  end

  @doc false
  def changeset(%{} = record, attributes \\ %{}) do
    record
      |> cast(attributes, [:name, :host])
      |> validate_required([:name, :host])
      |> assoc_constraint(:game_table)
      |> assoc_constraint(:account)
      |> assoc_constraint(:game_robot)
      |> Kempelen.Slugs.Name.maybe_generate_slug
      |> Kempelen.Slugs.Name.unique_constraint
      |> put_assoc(:game_robot, attributes[:game_robot])
      |> put_assoc(:account, attributes[:account])
      |> put_assoc(:game_table, attributes.game_table)
  end
end
#Ecto.Changeset<
  action: nil,
  changes: %{
    game_play: #Ecto.Changeset<action: :update, changes: %{}, errors: [],
     data: #Kempelen.Models.GamePlay<>, valid?: true>,
    game_player: #Ecto.Changeset<action: :update, changes: %{}, errors: [],
     data: #Kempelen.Models.GamePlayer<>, valid?: true>,
    game_round: #Ecto.Changeset<action: :update, changes: %{}, errors: [],
     data: #Kempelen.Models.GameRound<>, valid?: true>
  },
  errors: [],
  data: #Kempelen.Models.GameAct<>,
  valid?: true
>