Are the items “preloaded” with an empty list, or are there actual items? If it’s empty I suspect there’s a difference in the test ctxt
’s cart struct metadata states.
change/2
added support for assocs and embeds in v2.2.0-rc.0
about 7 years ago and has called Ecto.Changeset.Relation.load!/2
since then.
@doc """
Loads the relation with the given struct.
Loading will fail if the association is not loaded but the struct is.
"""
def load!(%{__meta__: %{state: :built}}, %NotLoaded{__cardinality__: cardinality}) do
cardinality_to_empty(cardinality)
end
def load!(struct, %NotLoaded{__field__: field}) do
raise "attempting to cast or change association `#{field}` " <>
"from `#{inspect struct.__struct__}` that was not loaded. Please preload your " <>
"associations before manipulating them through changesets"
end
def load!(_struct, loaded), do: loaded
defp cardinality_to_empty(:one), do: nil
defp cardinality_to_empty(:many), do: []
This function raises if the association isn’t loaded on the parent schema when the parent’s metadata state isn’t :built
, otherwise it returns a default empty value depending on the relation’s cardinality.
built_cart = %MyApp.Carts.Cart{}
assoc_items = built_cart.cart_items
assert Ecto.get_meta(built_cart, :state) == :built
assert is_struct(assoc_items, Ecto.Association.NotLoaded)
assert Ecto.Changeset.Relation.load!(built_cart, assoc_items) == []
%{cart: ctxt_cart} = ctxt
assoc_items = ctxt_cart.cart_items
assert Ecto.get_meta(ctxt_cart, :state) == :loaded
assert is_struct(assoc_items, Ecto.Association.NotLoaded)
assert_raise RuntimeError, fn ->
Ecto.Changeset.Relation.load!(ctxt_cart, assoc_items) == []
end