Skip to content

Commit 1ff25f6

Browse files
authored
Fix changed? for removed one relations (#4754)
1 parent e0aa6e1 commit 1ff25f6

2 files changed

Lines changed: 24 additions & 0 deletions

File tree

‎lib/ecto/changeset.ex‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -581,6 +581,8 @@ defmodule Ecto.Changeset do
581581
end
582582
end
583583

584+
defp relation_changed?(:one, nil), do: true
585+
584586
defp relation_changed?(:one, changeset) do
585587
changeset.action != :update or changeset.changes != %{}
586588
end

‎test/ecto/changeset_test.exs‎

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,8 @@ defmodule Ecto.ChangesetTest do
9898
belongs_to :category, Ecto.ChangesetTest.Category, references: :category_id, source: :cat_id
9999
has_many :comments, Ecto.ChangesetTest.Comment, on_replace: :delete
100100
has_one :comment, Ecto.ChangesetTest.Comment
101+
has_one :deletable_comment, Ecto.ChangesetTest.Comment, on_replace: :delete
102+
has_one :nilify_comment, Ecto.ChangesetTest.Comment, on_replace: :nilify
101103
end
102104
end
103105

@@ -878,6 +880,26 @@ defmodule Ecto.ChangesetTest do
878880
end
879881
end
880882

883+
test "changed?/3 returns true when a cardinality-one association is removed" do
884+
comment = %Comment{id: 1}
885+
886+
changeset =
887+
%Post{deletable_comment: comment}
888+
|> change()
889+
|> put_assoc(:deletable_comment, nil)
890+
891+
assert changeset.changes.deletable_comment == nil
892+
assert changed?(changeset, :deletable_comment)
893+
894+
changeset =
895+
%Post{nilify_comment: comment}
896+
|> cast(%{"nilify_comment" => nil}, [])
897+
|> cast_assoc(:nilify_comment)
898+
899+
assert changeset.changes.nilify_comment == nil
900+
assert changed?(changeset, :nilify_comment)
901+
end
902+
881903
test "fetch_field/2" do
882904
changeset = changeset(%Post{body: "bar"}, %{"title" => "foo"})
883905

0 commit comments

Comments
 (0)