@@ -45,6 +45,7 @@ defmodule Ecto.Repo.HasAssocTest do
4545 has_one :on_delete_nilify_assoc , MyAssoc , on_delete: :nilify_all
4646 has_many :assocs , MyAssoc , on_replace: :delete
4747 has_many :ordered_assocs , MyAssoc , on_replace: :delete , change_order: :unique_safe
48+ has_many :ordered_nilify_assocs , MyAssoc , on_replace: :nilify , change_order: :unique_safe
4849 has_many :delete_assocs , MyAssoc
4950 has_many :on_delete_delete_assocs , MyAssoc , on_delete: :delete_all
5051 has_many :on_delete_nilify_assocs , MyAssoc , on_delete: :nilify_all
@@ -435,6 +436,30 @@ defmodule Ecto.Repo.HasAssocTest do
435436 assert tu < ti
436437 end
437438
439+ test "updating assocs with change_order: :unique_safe and on_replace: :nilify" do
440+ sample1 = % MyAssoc { id: 10 , x: "xyz" , my_schema_id: 1 } |> Ecto . put_meta ( state: :loaded )
441+ sample2 = % MyAssoc { id: 11 , x: "abc" , my_schema_id: 1 } |> Ecto . put_meta ( state: :loaded )
442+
443+ changeset =
444+ % MySchema { id: 1 , ordered_nilify_assocs: [ sample1 , sample2 ] }
445+ |> Ecto.Changeset . cast (
446+ % { x: "abc" , ordered_nilify_assocs: [ % { id: 12 , x: "xyz" } , % { id: 10 , x: "tuv" } ] } ,
447+ [ :x ]
448+ )
449+ |> Ecto.Changeset . cast_assoc ( :ordered_nilify_assocs )
450+
451+ TestRepo . update! ( changeset )
452+ # Parent
453+ assert_received { :update , _ }
454+ # Assoc changes
455+ assert_received { :update , % { filters: [ id: 10 ] , order: tu1 } }
456+ assert_received { :update , % { filters: [ id: 11 ] , order: tu2 } }
457+ assert_received { :insert , % { order: ti } }
458+
459+ assert tu1 < ti
460+ assert tu2 < ti
461+ end
462+
438463 test "replacing assocs on update on_replace: :delete" do
439464 sample = % MyAssoc { id: 10 , x: "xyz" } |> Ecto . put_meta ( state: :loaded )
440465
0 commit comments