Elixir Phoenix/Exto-更新嵌入多个记录时发生更改集错误

Elixir Phoenix/Exto-更新嵌入多个记录时发生更改集错误,elixir,phoenix-framework,ecto,Elixir,Phoenix Framework,Ecto,在我的Phoenix应用程序中,当尝试使用嵌入多个关系更新模型时,我在exto.Changeset.change/2中遇到了一个无函数子句匹配错误。我读过文档,也看过其他关于这方面的帖子,但我不知道我做错了什么 首先,这里是错误: ** (FunctionClauseError) no function clause matching in Ecto.Changeset.change/2 (ecto) lib/ecto/changeset.ex:307: Ecto.Changeset.c

在我的Phoenix应用程序中,当尝试使用
嵌入多个
关系更新模型时,我在exto.Changeset.change/2中遇到了一个
无函数子句匹配错误。我读过文档,也看过其他关于这方面的帖子,但我不知道我做错了什么

首先,这里是错误:

** (FunctionClauseError) no function clause matching in Ecto.Changeset.change/2
    (ecto) lib/ecto/changeset.ex:307: Ecto.Changeset.change(%{"content" => "<p>Nice to see you</p>", "duration" => 15, "id" => "93387d2d-a6ed-4902-911f-4dc1525aca2b"}, %{})
    (ecto) lib/ecto/changeset/relation.ex:196: Ecto.Changeset.Relation.on_replace/2
    (ecto) lib/ecto/changeset/relation.ex:299: Ecto.Changeset.Relation.reduce_delete_changesets/5
    (ecto) lib/ecto/changeset.ex:691: Ecto.Changeset.cast_relation/4
    (myapp) web/models/agenda.ex:20: MyApp.Agenda.changeset/2
agenda\u page.ex

defmodule MyApp.Agenda do
  use MyApp.Web, :model

  @primary_key {:id, :string, []}
  @derive {Phoenix.Param, key: :id}
  schema "agenda" do
    field :name, :string
    embeds_many :pages, MyApp.AgendaPage, on_replace: :delete
  end

  def changeset(struct, params \\ %{}) do
    struct
    |> cast(params, [:name])
    |> cast_embed(:pages)
    |> validate_required([:name])
  end
end
defmodule MyApp.AgendaPage do
  use MyApp.Web, :model

  embedded_schema do
    field :content, :string
    field :duration, :integer
  end

  def changeset(struct, params \\ %{}) do
    struct
    |> cast(params, [:content, :duration])
  end
end
def update(conn, %{"id" => id, "agenda" => agenda_params}) do
  agenda = Repo.get!(Agenda, id)
  changeset = Agenda.changeset(agenda, agenda_params)

  case Repo.update(changeset) do
    {:ok, agenda} ->
      json conn, %{status: "ok", agenda: agenda}
    {:error, changeset} ->
      errors = parse_errors(changeset)
      IO.inspect errors
      json(conn |> put_status(400), %{status: "error", message: "Failed to update Agenda", errors: errors})
  end
end
以及来自
agenda\u controller.ex的
update
操作

defmodule MyApp.Agenda do
  use MyApp.Web, :model

  @primary_key {:id, :string, []}
  @derive {Phoenix.Param, key: :id}
  schema "agenda" do
    field :name, :string
    embeds_many :pages, MyApp.AgendaPage, on_replace: :delete
  end

  def changeset(struct, params \\ %{}) do
    struct
    |> cast(params, [:name])
    |> cast_embed(:pages)
    |> validate_required([:name])
  end
end
defmodule MyApp.AgendaPage do
  use MyApp.Web, :model

  embedded_schema do
    field :content, :string
    field :duration, :integer
  end

  def changeset(struct, params \\ %{}) do
    struct
    |> cast(params, [:content, :duration])
  end
end
def update(conn, %{"id" => id, "agenda" => agenda_params}) do
  agenda = Repo.get!(Agenda, id)
  changeset = Agenda.changeset(agenda, agenda_params)

  case Repo.update(changeset) do
    {:ok, agenda} ->
      json conn, %{status: "ok", agenda: agenda}
    {:error, changeset} ->
      errors = parse_errors(changeset)
      IO.inspect errors
      json(conn |> put_status(400), %{status: "error", message: "Failed to update Agenda", errors: errors})
  end
end
iex
终端中,我可以使用
MyApp.Repo.get(MyApp.agenda,“default\u agenda”)
访问现有议程,该议程返回以下记录:

%MyApp.Agenda{__meta__: #Ecto.Schema.Metadata<:built, "agenda">,
 id: "default_agenda", name: "Default Agenda",
 pages: [%{"content" => "<p>This is the default agenda</p>", "duration" => 10,
"id" => "0849862a-0794-4466-88a3-6052da360ca0"},
%{"content" => "<p>Nice to see you</p>", "duration" => 15,
"id" => "93387d2d-a6ed-4902-911f-4dc1525aca2b"}]}

但是试图通过我的更新操作运行此数据会产生错误。有人能提供一些指导吗?

首先,以下内容看起来不太正确:

%MyApp.Agenda{__meta__: #Ecto.Schema.Metadata<:built, "agenda">,
 id: "default_agenda", name: "Default Agenda",
 pages: [%{"content" => "<p>This is the default agenda</p>", "duration" => 10,
"id" => "0849862a-0794-4466-88a3-6052da360ca0"},
%{"content" => "<p>Nice to see you</p>", "duration" => 15,
"id" => "93387d2d-a6ed-4902-911f-4dc1525aca2b"}]}

是的,你是对的-架构似乎有问题。我需要回溯一点,会让你知道的。我对
id
问题有预感,但不确定。史蒂夫,你就是那个人!史蒂夫,你给我指明了正确的方向,尽管我还得想办法解决这个问题。关键是,当我得到插入的记录时,它没有保留对嵌入模型的引用-我得到的是
页面:[%{“content”…
而不是
页面:[%MyApp.AgendaPage{“content”…
id
问题也是一个问题,但这是主要问题。我实际上没有使用Postgres-使用一个实验性的DynamoDB适配器…因此需要找出如何保留该结构。我能够通过手动将模型引用添加到传递给变更集的第一个参数来成功进行更新。Steve,非常感谢你的观点!