I just tried this example and worked:
This are the shemas:
Artist:
defmodule Music.Artist do
use Ecto.Schema
import Ecto.Changeset
alias Music.{Artist, Album}
schema "artists" do
field(:name)
timestamps()
has_many(:albums, Album)
end
def changeset(%Artist{} = artist, params) do
artist
|> cast(params, [:name])
|> validate_required([:name])
|> cast_assoc(:albums)
end
end
Album
defmodule Music.Album do
use Ecto.Schema
import Ecto.Changeset
alias Music.{Artist, Track, Genre}
schema "albums" do
field(:title, :string)
timestamps()
belongs_to(:artist, Artist)
has_many(:tracks, Track)
end
def changeset(album, params) do
album
|> cast(params, [:title])
|> validate_required([:title])
|> cast_assoc(:tracks)
end
end
Track
defmodule Music.Track do
use Ecto.Schema
import Ecto.Changeset
alias Music.Album
schema "tracks" do
field(:title, :string)
timestamps()
belongs_to(:album, Album)
end
def changeset(track, params) do
track
|> cast(params, [:title])
|> validate_required([:title])
end
end
This are the parameters
params =
%{
"name" => "My name",
"albums" => [
%{
"title" => "El Primero",
"tracks" => [
%{"title" => "Mi primer cancion"}
]
},
]
}
This is the iex:
iex(4)> Music.Artist.changeset(%Artist{}, params)
This is the result:
#Ecto.Changeset<
action: nil,
changes: %{
albums: [
#Ecto.Changeset<
action: :insert,
changes: %{
title: "El Primero",
tracks: [
#Ecto.Changeset<
action: :insert,
changes: %{title: "Mi primer cancion"},
errors: [],
data: #Music.Track<>,
valid?: true
>
]
},
errors: [],
data: #Music.Album<>,
valid?: true
>
],
name: "My name"
},
errors: [],
data: #Music.Artist<>,
valid?: true
>
Hope this helps.
Best regards,