I had a schema defined as below. Notice that I omitted the schema name for the embed.
defmodule MySchema do
schema "my_schema" do
field :some_field, :string
embeds_one :example_embed do
field :test_field, :string
end
end
end
This led to an error while casting the embed:
** (ArgumentError) errors were found at the given arguments:
* 1st argument: not an atom
:erlang.apply([do: :ok], :__schema__, [:primary_key])
(ecto 3.8.4) lib/ecto/changeset/relation.ex:116: Ecto.Changeset.Relation.cast/5
(ecto 3.8.4) lib/ecto/changeset.ex:810: Ecto.Changeset.cast_relation/4
Another weird thing was that when I inspect the fields in my schema, I find that the fields in the embeded schema are now part of the main schema:
Before calling __embeds_one__, the arguments are evaluated, so field(:test_field, :string) runs in the context of the schema’s block - that’s why the field appears on the schema.
field always returns :ok, so __embeds_one__ is called with a “schema” that’s a keyword list [do: :ok] which cast_relation crashes on.