This is an example from one of the very useful “FullstackPhoenix” tutorials, namely:
# lib/tutorial/shop/data.ex
defmodule Tutorial.Shop.Data do
use Ecto.Schema
import Ecto.Changeset
@primary_key false
embedded_schema do
field :size, :string
field :color, :string
end
@doc false
def changeset(option, attrs) do
option
|> cast(attrs, [:size, :color])
|> validate_required([])
end
end
When saving the record, which embeds_one of the above, the whole “embedded_schema” gets stored, including fields, which are not set. This seems to make sense to me. At least as default behaviour. Out of curiosity – the question: is there a switch/option/other simple method, which would make it store only the fields, which are actually used/set?
Good question. When I don’t set it, it writes nil into the field. The same would happen if I chose to set it to "". So maybe what I am thinking about is more like “don’t write empty / unset fields”. The reason for asking is more a curiosity than necessity, although I imagine that if something is set only on very rare occasions, like once in thousands of records, then simply not storing it would be more effective.
Right. I guess this is the answer as it probably wouldn’t be worth the effort to handle some special cases for structs, which then end up as maps stored as JSON.
You could write a custom Ecto type which only stores fields which are not nil. The wire protocol is forgiving. Your custom type can have a type of :map. In dump/1 you can emit a trimmed-down Map.
I don’t think it’s worth the effort in the case I have at hand. Was curious if somebody thought of such scenario and maybe provided an option OOB. But yes, if dumping whole maps becomes an issue then such custom type might help, TNX.