I have a schema like this:
embeds_one :product_profile, ProductProfile, on_replace: :delete, load_in_query: false
I use product_profile as a form/helper structure in LiveView (e.g. live_select), not something I want to persist.
However, I also rely on it for more than just selecting a product: it drives a lot of calculations (pricing, discounts, etc.), so keeping it around in the changeset is very convenient.
From it, I derive product_id inside the changeset:
|> cast_embed(:product_profile)
|> sync_product_id()
Before inserting, I manually transform the params:
filtered_items =
proposal_items_list
|> Enum.map(fn {_i, item} ->
product_id = get_in(item, ["product_profile", "product_id"])
item
|> Map.put("product_id", product_id)
|> Map.delete("product_profile")
end)
This works, but feels a bit manual / hacky.
Is this considered an acceptable pattern in Ecto (using an embedded schema mainly as a transient helper for UI + calculations, while extracting a persisted field from it), or is there a more idiomatic approach to avoid reshaping the params before insert?






















