Hello everyone. I want to use schemaless changesets to validate external data. And I wonder how to properly use embeds with them.
Let’s assume I want to validate the nested map under the user key in my params payload. And I want my data to be a map in the end. So to get this work I managed to write this “hack”:
defmodule Params do
import Ecto.Changeset
@user_types %{id: :integer}
@user_fields Map.keys(@user_types)
@types %{
name: :string,
page: :integer,
page_size: :integer,
ages: {:array, :integer},
user:
{:embed,
elem(
Ecto.ParameterizedType.init(Ecto.Embedded,
cardinality: :one,
related: __MODULE__,
field: :user
),
2
)}
}
@default %{
page: 1,
page_size: 10
}
@fields Map.keys(@types) -- [:user]
def build(entity \\ @default, attrs \\ %{}) do
entity
|> changeset(attrs)
|> apply_action(:insert)
end
def changeset(entity, attrs) do
{entity, @types}
|> cast(attrs, @fields)
|> cast_embed(:user, with: &user_changeset/2)
end
def user_changeset(entity, attrs) do
{entity, @user_types}
|> cast(attrs, @user_fields)
end
def __schema__(:primary_key), do: []
def __struct__, do: %{}
end
Although it’s kinda working doesn’t seems good. As I need to define __schema__/1 and __struct__/0 functons with custom behavior while setting related key to not being relation module, but parent module.
I want to know better approaches to how to validate nested data using schemaless changesets. Or maybe that’s not proper usage of schemaless changeset. And I need to use schema/embedded_schema to avoid “hacking” ?






















