but embeds_many(:body_parts, BodyPart) (obviously) gives me a list.
Is there a clean way to do that? I could just post-process the Person but my schema would be lying then.
If that helps I could change the input to a map.
defmodule BodyPart do
use Ecto.Schema
@primary_key false
embedded_schema do
field(:id, :string)
field(:count, :integer)
end
def changeset(body_part, params) do
Ecto.Changeset.cast(body_part, params, [:id, :count])
end
end
defmodule Person do
use Ecto.Schema
@primary_key false
embedded_schema do
field(:id, :integer)
...
embeds_many(:body_parts, BodyPart)
end
def changeset(params) do
%Person{}
|> Ecto.Changeset.cast(params, [:id, :name, :age, :hobbies, :friends])
|> Ecto.Changeset.cast_embed(:body_parts)
end
end
I’m not using a database but use Ecto.Schema to load JSON into Elixir Structs.
The IDs are used by other objects to reference objects in another collection. So I need the collections indexed by ID.
What I currently do is use embeds_many and transform the list to a map (pull out the ID).
The only problem is, that the schema does not reflect reality now. Don’t see how this would get better by using embeds_one.
I thought about that, but after implementing Ecto.Enum because I didn’t understand it I’d rather ask if there is a builtin way. I’m not sure if its worth the effort for just to have a clean schema. Actually I’m not sure if I shouldnt give up the DB-free path and just use Ecto and postgres.
The transformation of the list to map indicates a core domain model requirement, where the map has a meaning for indexing. And from the JSON’s model perspective represented by schema, it’s ok to have a list. So, It’s an option to have two models and make a transformation between them on the controller level.