Well, I have the following migrations:
defmodule Test.Repo.Migrations.AddStuff do
use Ecto.Migration
def change do
create table(:users) do
add :name, :string
end
create table(:posts) do
add :body, :text
add :user_id, references(:users, on_delete: :delete_all)
end
create table(:comments) do
add :body, :string
add :post_id, references(:posts, on_delete: :delete_all)
end
end
end
and schemas
defmodule Test.User do
use Ecto.Schema
schema "users" do
field :name, :string
has_many :posts, Test.Post
end
end
defmodule Test.Post do
use Ecto.Schema
schema "posts" do
field :body, :string
has_many :comments, Test.Comment
belongs_to :user, Test.User
end
end
defmodule Test.Comment do
use Ecto.Schema
schema "comments" do
field :body, :string
belongs_to :post, Test.Post
end
end
and testing this in iex
iex(1)> {:ok, user} = Test.Repo.insert(%Test.User{name: "asdfg"})
{:ok, %Test.User{id: 1, ...}}
iex(2)> {:ok, post} = user |> Ecto.build_assoc(:posts, %{body: "asd"}) |> Test.Repo.insert()
{:ok, %Test.Post{id: 1, ...}}
iex(3)> {:ok, comment} = post |> Ecto.build_assoc(:comments, %{body: "asd"}) |> Test.Repo.insert()
{:ok, %Test.Comment{id: 1, ...}}
iex(4)> Test.Repo.delete(user)
{:ok, %Test.User{id: 1, ...}}
works as expected.
You might want to add ON DELETE CASCADE
to how your create you tables in postgres, (which is what references(table, on_delete: :delete_all)
does in the migrations above). See https://stackoverflow.com/questions/33939169/elixir-delete-many-to-many-association for a very similar question.