Im getting problem with insert schema with embeds_many when using changeset
This is the product schema
defmodule Hello.Catalog.Product do
use Ecto.Schema
import Ecto.Changeset
schema "products" do
field :title, :string
embeds_many :variants, Hello.Catalog.Variant, on_replace: :delete
timestamps(type: :utc_datetime)
end
@doc false
def changeset(product, attrs) do
product
|> cast(attrs, [:title])
|> cast_embed(:variants,
with: &Hello.Catalog.Variant.changeset/3,
drop_param: :variants_drop,
sort_param: :variants_sort
)
|> validate_required([:title])
end
end
variant schema
defmodule Hello.Catalog.Variant do
use Ecto.Schema
import Ecto.Changeset
embedded_schema do
field :name, :string
field :price, :decimal
field :sku, :string
end
def changeset(variant, attrs, _index) do
variant
|> cast(attrs, [:name, :price, :sku])
|> validate_required([:name, :price, :sku])
end
end
When i use
Product.changeset(%Product{}, %{
"title" => "te",
"variants" => [
%{"name" => "t", "price" => "1", "sku" => "a"}
]
})
|> Repo.insert()
It shows
** (Ecto.ChangeError) value
`[%Hello.Catalog.Variant{id: "402143f5-e875-4976-86c0-6aeab3420946",name: "t", price: Decimal.new("1"), sku: "a"}]`
for `Hello.Catalog.Product.variants` in `insert` does not match type
#Ecto.Embedded<%Ecto.Embedded{cardinality: :many, field: :variants, owner: Hello.Catalog.Product, related: Hello.Catalog.Variant, on_cast: nil, on_replace: :delete, unique: true, ordered: true}>
But when i insert product struct without changeset, it works
%Product{title: "T", variants: [%Variant{name: "TEST", sku: "t1", price: 1.0}]}
|> Repo.insert()
I found a related topic https://elixirforum.com/t/using-repo-insert-all-when-your-schema-has-embeds-many/14219/, but its uncleared.
Can someone explain why this changeset insert method doesnt work.