【发布时间】:2017-07-21 21:37:08
【问题描述】:
在我的 Phoenix 应用程序中,我在尝试更新具有 embeds_many 关系的模型时收到 no function clause matching in Ecto.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,嵌入模型是AgendaPage。模型定义如下:
agenda.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
agenda_page.ex
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
还有来自agenda_controller.ex 的update 操作
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_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"}]}
agenda_params 的示例将被传递到控制器操作中的变更集中,如下所示:
%{
"id" => "default_agenda",
"name" => "Default Agenda",
"pages" => [
%{
"content" => "<p>foo</p>",
"duration" => 10,
"id" => "0849862a-0794-4466-88a3-6052da360ca0"
},
%{
"content" => "<p>bar</p>",
"duration" => 15,
"id" => "93387d2d-a6ed-4902-911f-4dc1525aca2b"
}
]
}
但尝试通过我的更新操作运行此数据会产生错误。谁能提供一些指导?
【问题讨论】:
标签: elixir phoenix-framework ecto