Difference between embedded schema and schema that is never inserted

What’s the difference between creating a regular ecto schema that I never use with a database insert, vs creating an embedded schema?

What are the reasons to use one over the other?

At the very least a regular Ecto Schema has mechanics to link it up to database tables, such as taking the table name as a parameter. Per the docs (Ecto.Schema — Ecto v3.10.3):

schema/2 is typically used to map data from a persisted source, usually a database table, into Elixir structs and vice-versa. For this reason, the first argument of schema/2 is the source (table) name. Structs defined with schema/2 also contain a __meta__ field with metadata holding the status of the struct, for example, if it has been built, loaded or deleted.

On the other hand, embedded_schema/1 is used for defining schemas that are embedded in other schemas or only exist in-memory. For example, you can use such schemas to receive data from a command line interface and validate it, without ever persisting it elsewhere. Such structs do not contain a __meta__ field, as they are never persisted.

So, assuming there aren’t any attempts to validate the Ecto Schema against its configuration, you could probably dummy up a link and it might even work. Of course, you’re probably also going to be able to pass that data using the resulting struct to functions expecting to be able to operate on something that looks like a table which in this case wouldn’t exist; an embedded schema wouldn’t have such an issue.

So aside from just being good form to pick the correct Ecto macro to using in representing the data, there could be downsides including bogus metadata and being able to pass data to functions expecting a database. To be clear: I haven’t tested these possible issues nor know to what extent they may appear in practice… its just easier to use the right tool for the job and not sweat it.

1 Like