Skip to content

Allow loader/dumper be passed through Ecto.embedded_load / Ecto.embedded_dump - #4782

Open
LostKobrakai wants to merge 2 commits into
elixir-ecto:masterfrom
LostKobrakai:bm/embedded-schema-conversion
Open

Allow loader/dumper be passed through Ecto.embedded_load / Ecto.embedded_dump#4782
LostKobrakai wants to merge 2 commits into
elixir-ecto:masterfrom
LostKobrakai:bm/embedded-schema-conversion

Conversation

@LostKobrakai

@LostKobrakai LostKobrakai commented Aug 13, 2026

Copy link
Copy Markdown
Contributor

I'm working on a map based type mirroring embeds_many for transforming back and forth between ecto schema struct data and json. Ecto.ParameterizedType seems to support that usecase without much issue. Ecto.embedded_load(OuterSchema, %{…}, :json) works.

embedded_schema do
  field :items, MapOf, of: Item, default: %{}
  field :rooms, MapOf, of: Room, default: %{}
end

However the implementation needed to hardcode :json as the format for dumping/loading (just showing one side, but it's a mirror issue for both)

@impl true
def load(data, loader, %{of: schema}) when is_map(data) do
  loaded =
    Map.new(data, fn {key, value} ->

      # Copy implementation of `Ecto.embedded_load`
      # {key, Ecto.Schema.Loader.unsafe_load(schema, value, loader)}

      # Pull dynamic format from anonymous function 
      # {key, Ecto.embedded_load(schema, value, hd(Function.info(loader).env)}

      # Hardcoded format, instead of having it provided to the callback
      {key, Ecto.embedded_load(schema, value, :json)}
    end)

  {:ok, loaded}
end

Both Ecto.embedded_load/3 as well as the loader passed to c:load/3 are &Ecto.Type.embeded_load(&1, &2, format), so it's as far as I can see mostly an issue of being able to compose those things, where Ecto.embedded_load/3 doesn't really expect someone to already have the whole dumper callback at hand.

https://github.com/elixir-ecto/ecto/blob/master/lib/ecto/type.ex#L431 is where the anonymous function passed to the loader is from.

This PR would be a simple solution here, though not sure if there's sideeffects I'm missing. One benefit to it however is that it's truely scoped to the embedded data usecase and doesn't affect loading from database tables.

@josevalim

Copy link
Copy Markdown
Member

Yup, this looks good to me!

@LostKobrakai
LostKobrakai marked this pull request as ready for review August 14, 2026 18:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants