Ecto:如何使用 put_assoc 在一次更新中更新和插入关联
Ecto: How to update and insert association in one update using put_assoc
我正在尝试编写一个单一的变更集来更新模型并插入关联。我找不到有关如何使用 put_assoc/4
的示例
order = order
|> Proj.Order.changeset(%{state: "error", error_count: order.error_count + 1})
|> Ecto.Changeset.put_assoc(
:order_errors,
[Proj.OrderError.changeset(%Proj.OrderError{}, %{reason: "not_found"})])
|> Proj.Repo.update!
这会打印出以下错误:
** (Ecto.InvalidChangesetError) could not perform update because changeset is invalid.
* Changeset changes
%{order_errors: [%Ecto.Changeset{action: :insert, changes: %{id: nil, inserted_at: nil, order_id: nil, reason: "not_found", updated_at: nil}, constraints: [], errors: [order_id: "can't be blank"], filters: %{}, model: %Proj.OrderError{__meta__: #Ecto.Schema.Metadata<:built>, id: nil, inserted_at: nil, order: #Ecto.Association.NotLoaded<association :order is not loaded>, order_id: nil, reason: nil, updated_at: nil}, optional: [], opts: [], params: %{"reason" => "not_found"}, prepare: [], repo: nil, required: [:order_id, :reason], types: %{id: :id, inserted_at: Ecto.DateTime, order_id: :id, reason: :string, updated_at: Ecto.DateTime}, valid?: false, validations: []}], state: "error"}
* Changeset params
%{"error_count" => 1, "state" => "error"}
* Changeset errors
[]
我可以查看 put_assoc/4
的任何示例吗?我如何找到变更集无效的原因?
这样做的目的是希望新 order
能够预加载 order_errors
。
我在 Ecto tests 中找到了如何让它工作的方法。简而言之,只需删除 changeset
创建并直接使用新模型。
order = order
|> Proj.Order.changeset(%{state: "error", error_count: order.error_count + 1})
|> Ecto.Changeset.put_assoc(
:order_errors,
[%Proj.OrderError{reason: "not_found"}])
|> Proj.Repo.update!
我还是想知道如何理解原文的错误信息post
如put_assoc/4描述的有效值:
The given value may either be the association struct, a changeset for the given association or a map or keyword list of changes to be applied to the current association. On all cases, it is expected the keys to be atoms. If a map or keyword list are given and there is no association, one will be created.
如果您使用 changeset
,您应该使用现有的 %Proj.OrderError{}
,put_assoc/4
将自动为这个 changeset
执行 update
。
但对于其他情况,尤其是记录需要insert
,使用struct
,关键字列表或地图是更好的主意。
我正在尝试编写一个单一的变更集来更新模型并插入关联。我找不到有关如何使用 put_assoc/4
order = order
|> Proj.Order.changeset(%{state: "error", error_count: order.error_count + 1})
|> Ecto.Changeset.put_assoc(
:order_errors,
[Proj.OrderError.changeset(%Proj.OrderError{}, %{reason: "not_found"})])
|> Proj.Repo.update!
这会打印出以下错误:
** (Ecto.InvalidChangesetError) could not perform update because changeset is invalid.
* Changeset changes
%{order_errors: [%Ecto.Changeset{action: :insert, changes: %{id: nil, inserted_at: nil, order_id: nil, reason: "not_found", updated_at: nil}, constraints: [], errors: [order_id: "can't be blank"], filters: %{}, model: %Proj.OrderError{__meta__: #Ecto.Schema.Metadata<:built>, id: nil, inserted_at: nil, order: #Ecto.Association.NotLoaded<association :order is not loaded>, order_id: nil, reason: nil, updated_at: nil}, optional: [], opts: [], params: %{"reason" => "not_found"}, prepare: [], repo: nil, required: [:order_id, :reason], types: %{id: :id, inserted_at: Ecto.DateTime, order_id: :id, reason: :string, updated_at: Ecto.DateTime}, valid?: false, validations: []}], state: "error"}
* Changeset params
%{"error_count" => 1, "state" => "error"}
* Changeset errors
[]
我可以查看 put_assoc/4
的任何示例吗?我如何找到变更集无效的原因?
这样做的目的是希望新 order
能够预加载 order_errors
。
我在 Ecto tests 中找到了如何让它工作的方法。简而言之,只需删除 changeset
创建并直接使用新模型。
order = order
|> Proj.Order.changeset(%{state: "error", error_count: order.error_count + 1})
|> Ecto.Changeset.put_assoc(
:order_errors,
[%Proj.OrderError{reason: "not_found"}])
|> Proj.Repo.update!
我还是想知道如何理解原文的错误信息post
如put_assoc/4描述的有效值:
The given value may either be the association struct, a changeset for the given association or a map or keyword list of changes to be applied to the current association. On all cases, it is expected the keys to be atoms. If a map or keyword list are given and there is no association, one will be created.
如果您使用 changeset
,您应该使用现有的 %Proj.OrderError{}
,put_assoc/4
将自动为这个 changeset
执行 update
。
但对于其他情况,尤其是记录需要insert
,使用struct
,关键字列表或地图是更好的主意。