Ecto.Schema / Ecto.Changeset - optional, conditionally present fields

What you’re really looking for here is a “polymorphic embedded schema”, which is something that comes up every so often. I think someone even wrote a library for it, though I’ve never used it.

My personal opinion: If your data is unstructured, just use a map field (JSON column) and don’t worry so much about the schema - that’s what unstructured means, after all!

If your data is structured and you are worried about the schema, then you should probably be using actual tables. That’s what they’re for!

Of course, if you wanted to go in the opposite direction with an even more degenerate solution, I bet you could put the embedded schema in a virtual field and then parse it back out at the end of the parent’s changeset, drop the nulls, and dump it into a real map field. Of course, then your data wouldn’t be structured on the way out of the DB, but you could probably cook up a solution to that too if you really wanted. The Ecto.Type hack is probably better, though.