Skip to content

Instantly share code, notes, and snippets.

@mbklein
Last active February 13, 2020 21:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mbklein/ff32896a4ffc7f636198b68148f36d7b to your computer and use it in GitHub Desktop.
Save mbklein/ff32896a4ffc7f636198b68148f36d7b to your computer and use it in GitHub Desktop.
Ecto validation for non-nil embedded schema
defmodule MyApp.Data.Schemas.Foo do
use Ecto.Schema
import Ecto.Changeset
import MyApp.Data.Schemas.PrepareEmbed
alias MyApp.Data.Schemas.EmbeddedMap
schema "foo" do
embeds_one :embedded_map, EmbeddedMap, on_replace: :update
end
def changeset(item, attrs) do
item
|> cast(attrs, [])
|> prepare_embed(:embedded_map)
|> cast_embed(:embedded_map)
end
end
defmodule MyApp.Data.Schemas.PrepareEmbed do
def prepare_embed(%Ecto.Changeset{data: data, params: params} = change, field) do
with f <- to_string(field) do
case {Map.get(params, f), Map.get(data, f)} do
{nil, nil} ->
{:embed, field_spec} = change.data.__struct__.__schema__(:type, field)
params = Map.put(params, f, field_spec.related.__struct__ |> Map.from_struct())
Map.put(change, :params, params)
_ ->
change
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment