How I validate a array of objects inside a Object in request body with Ecto

Hello everyone I am trying to do a validation of a request body with Ecto the next scenario

“receiver”: {“emails”: [{
“template”: “letter”,
“format”: “pdf”,
“email”: “test@test.com
}]}

so far my approximation is, in the root module

defmodule Models.ValidateRebillRequest do
  use Ecto.Schema
  import Ecto.Changeset

  embedded_schema do
    field :client_id, :string
    field :uuid, :string
    field :transaction_id, :string
    **embeds_one :receiver, Models.ReceiverModel**


  def changeset(attributes) do
    %Models.ValidateRebillRequest{}
    |> cast(attributes, [:uuid, :client_id, :transaction_id])
    |> cast_embed(:document, with: &Models.RequestDocument.changeset/2, required: true)
    |> cast_embed(:receiver, with: &Models.ReceiverModel.changeset/2, required: true)
  end

in the module that contains the array i have

defmodule Models.ReceiverModel do
  use Ecto.Schema
  import Ecto.Changeset

  embedded_schema do
    embeds_one :emails, Models.ReceiverModelData
  end

  @spec changeset(any, any) :: none
  def changeset(data, attrs) do
    cast_embed(:emails, with: fn -> Models.ReceiverModelData.changeset(data, attrs) end)

  end
end

and in the module that contains the information I have this

defmodule Models.ReceiverModelData do
  use Ecto.Schema
  import Ecto.Changeset

  embedded_schema do
    field :template, :string
    field :format, :string
    field :email, :string
  end

  def changeset(data, attrs) do

    IO.inspect(data, label: "data")
    IO.inspect(attrs, label: "attrs")

    data
    |> cast(attrs, [:template, :format, :email])

  end
end

I am getting the following error, please if anyone has any idea how to validate I would greatly appreciate it!!

** (exit) an exception was raised:
** (FunctionClauseError) no function clause matching in Ecto.Changeset.cast_embed/3
(ecto 3.9.1) lib/ecto/changeset.ex:802: Ecto.Changeset.cast_embed(:emails, [with: #Function<1.118871002/0 in Models.ReceiverModel.changeset/2>], [])
(ecto 3.9.1) lib/ecto/changeset/relation.ex:137: Ecto.Changeset.Relation.do_cast/6
(ecto 3.9.1) lib/ecto/changeset/relation.ex:335: Ecto.Changeset.Relation.single_change/5
(ecto 3.9.1) lib/ecto/changeset/relation.ex:121: Ecto.Changeset.Relation.cast/5
(ecto 3.9.1) lib/ecto/changeset.ex:832: Ecto.Changeset.cast_relation/4
(issue 0.1.0) lib/models/validate_rebill_request.ex:25: Models.ValidateRebillRequest.validate_params/1
(issue 0.1.0) lib/issue_web/controllers/issue_controller.ex:37: IssueWeb.IssueController.rebill/2
(issue 0.1.0) lib/issue_web/controllers/issue_controller.ex:1: IssueWeb.IssueController.action/2
(issue 0.1.0) lib/issue_web/controllers/issue_controller.ex:1: IssueWeb.IssueController.phoenix_controller_pipeline/2
(phoenix 1.6.14) lib/phoenix/router.ex:354: Phoenix.Router.call/2
(issue 0.1.0) lib/issue_web/endpoint.ex:1: IssueWeb.Endpoint.plug_builder_call/2
(issue 0.1.0) lib/plug/debugger.ex:136: IssueWeb.Endpoint.“call (overridable 3)”/2
(issue 0.1.0) lib/issue_web/endpoint.ex:1: IssueWeb.Endpoint.call/2
(phoenix 1.6.14) lib/phoenix/endpoint/cowboy2_handler.ex:54: Phoenix.Endpoint.Cowboy2Handler.init/4
(cowboy 2.9.0) /home/gerson/Escritorio/dvz-eng-tickets/deps/cowboy/src/cowboy_handler.erl:37: :cowboy_handler.execute/2
(cowboy 2.9.0) /home/gerson/Escritorio/dvz-eng-tickets/deps/cowboy/src/cowboy_stream_h.erl:306: :cowboy_stream_h.execute/3
(cowboy 2.9.0) /home/gerson/Escritorio/dvz-eng-tickets/deps/cowboy/src/cowboy_stream_h.erl:295: :cowboy_stream_h.request_process/3
(stdlib 4.1.1) proc_lib.erl:240: :proc_lib.init_p_do_apply/3

  def changeset(%User{} = user, attrs \\ %{}) do
    user
    |> cast(attrs, [:full_name, :email])
    |> cast_embed(:profile, required: true, with: &profile_changeset/2)
  end

Going off the example above from the Embedded Schemas Ecto guide, cast_embed/3 expects a changeset struct aka your data as the first parameter followed by an atom aka your :emails as the second parameter. I’d suggest trying something like the below:

 def changeset(data, attrs) do
    cast_embed(data, :emails, with: &Models.ReceiverModelData.changeset/2)

Mixed up parameter ordering would also explain the error you’re seeing (FunctionClauseError) no function clause matching in Ecto.Changeset.cast_embed/3. If you’re new to Elixir, it’s important to remember that when piping into a function, the first parameter within the parentheses is actually the second parameter!
e.g. param1 |> some_function(param2) is equivalent to some_function(param1, param2)