Elixir Phoenix/Exto-更新嵌入多个记录时发生更改集错误
在我的Phoenix应用程序中,当尝试使用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
嵌入多个关系更新模型时,我在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,非常感谢你的观点!