Please explain Ecto.Type.embed_as/1

https://hexdocs.pm/ecto/Ecto.Type.html

Can anyone please explain what the following means?

embed_as(format)

embed_as(format :: atom()) :: :self | :dump

Dictates how the type should be treated inside embeds.

By default, the type is sent as itself, without calling dumping to keep the higher level representation. But it can be set to :dump to it is dumped before encoded.

Is this about embedded schemas? What’s it for? Also I don’t understand the “dumped before encoded” part. And shouldn’t this function have a default so I don’t have to implement it in all of my types.

1 Like

Yes this is about embedded schemas, hence the embed_… name. Ecto Types handle 3 represenations of data. The “input” data, which can be cast to the format used at runtime by elixir and the format used to persist the data into the database.

This was only true for non embedded fields though until v3.2. For embedded data ecto used to just take the runtime format and serialize it to json and back ignoring any behaviour of the dump/load callback. If the ecto type was e.g. meant to AES encode the data before persistance the behaviour would break in embedded schemas. With this new callback in place it can be chosen which behaviour you need, defaulting to the old way of handling things.

3 Likes

I’ve just updated one of my custom ecto types and leant that if you replace @behaviour Ecto.Type with use Ecto.Type in your type module you will get a default implementations of embed_as/1 (the default is :self) and equal?/2 (which defaults to term1 == term2). They are both overridable.

4 Likes

tnx @kip that helps!

If I understood correcrtly, the embed_as/1 callback allows then to specify if we bypass (return :self) or call the dump/1/load/1 callbacks (return :dump) when the Ecto Type is inside an embedded_schema.

But what does the format argument to embed_as/1 represent? What values can it take?

I’d expect it’s mostly future-proofing at this point. You can likely ignore it at the moment.

2 Likes