From a426b1de6cc439c665439d3418af446922d4a9b0 Mon Sep 17 00:00:00 2001 From: Greg Rychlewski Date: Thu, 2 Oct 2025 22:09:18 -0400 Subject: [PATCH] reset parent assoc when after nil prelaod --- lib/ecto/repo/schema.ex | 20 +++++++++++++++----- test/ecto/repo/belongs_to_test.exs | 14 ++++++++++++++ 2 files changed, 29 insertions(+), 5 deletions(-) diff --git a/lib/ecto/repo/schema.ex b/lib/ecto/repo/schema.ex index 06b24e9e3c..e2fedf5f60 100644 --- a/lib/ecto/repo/schema.ex +++ b/lib/ecto/repo/schema.ex @@ -1142,11 +1142,21 @@ defmodule Ecto.Repo.Schema do defp reset_parent?(changes, data, assoc) do %{field: field, owner_key: owner_key, related_key: related_key} = assoc - with %{^owner_key => owner_value} <- changes, - %{^field => %{^related_key => related_value}} when owner_value != related_value <- data do - true - else - _ -> false + case changes do + %{^owner_key => owner_value} -> + case data do + %{^field => %{^related_key => related_value}} when owner_value != related_value -> + true + + %{^field => nil} when owner_value != nil -> + true + + _ -> + false + end + + _ -> + false end end diff --git a/test/ecto/repo/belongs_to_test.exs b/test/ecto/repo/belongs_to_test.exs index c83cec8d1f..2eec498426 100644 --- a/test/ecto/repo/belongs_to_test.exs +++ b/test/ecto/repo/belongs_to_test.exs @@ -496,4 +496,18 @@ defmodule Ecto.Repo.BelongsToTest do assert updated_schema.assoc_id == 2 assert %Ecto.Association.NotLoaded{} = updated_schema.assoc end + + test "reset assoc when foreign key update results in a mismatch and parent is nil" do + schema = %MySchema{} |> TestRepo.insert!() |> TestRepo.preload(:assoc) + assert schema.assoc_id == nil + assert schema.assoc == nil + + updated_schema = + schema + |> Ecto.Changeset.change(%{assoc_id: 2}) + |> TestRepo.update!() + + assert updated_schema.assoc_id == 2 + assert %Ecto.Association.NotLoaded{} = updated_schema.assoc + end end