Insert/Update ecto 模型中的嵌套对象

Insert/Update nested objects in ecto model

使用

等模型
defmodule MyApp.StorageMovement do
  use MyApp.Web, :model

  schema "storage_movements" do
    field :name, :string
    field :reference_datetime, Timex.Ecto.DateTime
    has_many :storage_product_movements, MyApp.StorageProductMovement

    timestamps()
  end

  @doc """
  Builds a changeset based on the `struct` and `params`.
  """
  def changeset(struct, params \ %{}) do
    struct
    |> cast(parse_params_date(params), [:name, :reference_datetime])
    |> validate_required([:name, :reference_datetime])
  end
end

如何通过单个 post 请求更新关联值?例如,如果它包含带有 ID 的内容,则更新它,如果没有 ID,则创建它等等?

刚刚发现,如果你像这样更改模型:

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

  schema "storage_movements" do
    field :name, :string
    field :reference_datetime, Timex.Ecto.DateTime
    has_many :storage_product_movements, MyApp.StorageProductMovement, on_replace: :delete

    timestamps()
  end

  @doc """
  Builds a changeset based on the `struct` and `params`.
  """
  def changeset(struct, params \ %{}) do
    struct
    |> cast(parse_params_date(params), [:name, :reference_datetime])
    |> cast_assoc(:storage_product_movements, params["storage_product_movements"])
    |> validate_required([:name, :reference_datetime])
  end
end

它将自动遍历 params 子数组并创建没有 ID 的新实体,删除数据库中存在但不在 params 数组中的实体并更新具有 ID 的实体

我想你正在寻找 insert_or_update/2

来自文档:

result =
  case MyRepo.get(Post, id) do
    nil  -> %Post{id: id} # Post not found, we build one
    post -> post          # Post exists, let's use it
  end
  |> Post.changeset(changes)
  |> MyRepo.insert_or_update

case result do
  {:ok, struct}       -> # Inserted or updated with success
  {:error, changeset} -> # Something went wrong
end