Skip to content

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

Draft
LostKobrakai wants to merge 1 commit into
elixir-ecto:masterfrom
LostKobrakai:bm/embedded-schema-conversion
Draft

Allow loader/dumper be passed through Ecto.embedded_load / Ecto.embedded_dump#4782
LostKobrakai wants to merge 1 commit 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.

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.

1 participant