From Ecto.Changeset ā Ecto v3.11.1
The given value may either be the embed struct, a changeset for the given embed or a map or keyword list of changes to be applied to the current embed. On all cases, it is expected the keys to be atoms. If a map or keyword list are given and there is no embed, one will be created.
However, when I pass the whole struct as value (ecto 2.2.6), it just ignores the value. Am I interpreting the documentation incorrectly? Or is it really a bug in Ecto?
(Note: this is for Zendesk API )
defmodule Organization do
use Ecto.Schema
@primary_key {:id, :integer, autogenerate: false}
embedded_schema do
field(:name, :string)
embeds_one(:organization_fields, OrganizationFields, on_replace: :update)
end
end
defmodule OrganizationFields do
use Ecto.Schema
alias Ecto.Changeset
@primary_key false
embedded_schema do
field(:key1, :string)
field(:key2, :string)
end
end
defmodule EctoEmbedTest do
use ExUnit.Case
alias Ecto.Changeset
@existing_struct %Organization{
id: 1234,
name: "foo",
organization_fields: %OrganizationFields{key1: "foo", key2: "bar"}
}
@new_fields_map %{key1: "bar", key2: "bar"}
@new_fields_struct struct!(OrganizationFields, @new_fields_map)
test "put_embed with changeset" do
changeset =
@existing_struct
|> Ecto.Changeset.change()
|> Ecto.Changeset.put_embed(
:organization_fields,
Changeset.change(@existing_struct.organization_fields, @new_fields_map)
)
%Changeset{changes: %{organization_fields: %Changeset{changes: org_changes}}} = changeset
assert %{key1: "bar"} == org_changes
end
test "put_embed with map" do
changeset =
@existing_struct
|> Changeset.change()
|> Changeset.put_embed(:organization_fields, @new_fields_map)
%Changeset{changes: %{organization_fields: %Changeset{changes: org_changes}}} = changeset
assert %{key1: "bar"} == org_changes
end
test "put_embed with struct" do
changeset =
@existing_struct
|> Ecto.Changeset.change()
|> Ecto.Changeset.put_embed(
:organization_fields,
@new_fields_struct
)
%Changeset{changes: %{organization_fields: %Changeset{changes: org_changes}}} = changeset
assert %{key1: "bar"} == org_changes
end
end
All tests passed except put_embed with struct
, which gives empty changes
.
Note: I found two related topics in this forum, and both suggested to pass changeset.