krainboltgreene
Why does `embeds_many` enforce a default of `[]`?
Today I noticed that when defining a embeds_many the new struct has a default of [] which is confusing since:
- You can have
jsonb[]columns with a default ofNULL embeds_onehas a default ofnil- You can’t define your own default!
I ask because I have code that expected it to behave like other fields and also because {} in postgres is twice as expensive as an null value in postgres:
ecto/lib/ecto/schema.ex at master · elixir-ecto/ecto · GitHub.
Looks like it was committed 7 years ago: Remove containers in favor of strategies · elixir-ecto/ecto@7f052d9 · GitHub
Most Liked
josevalim
This is it. ![]()
krstfk
I would argue this is the only correct default. Embeds many represents associated records of which there can be 0 or more.
The number of records in NULL would be undefined, which would be incorrect.
LostKobrakai
Embeds are modeled to align closely with assocs and for assocs empty set doesn‘t mean there‘s a column somewhere set to NULL, but it means there‘s no rows at all. It makes sense to default that field to empty list, because as mentioned before it‘s much cleaner not to check for nil and empty list everywhere.
krstfk
I’m not gonna die on that hill, but -to me- the data you’re suggesting is something like Maybe[OkList]. So you basically have two inhabitants of your type: Some(maybe_empty_list) and None (null).
Personally I’d model that as an embed one.
Again to me embeds_many suggests a list and I’m fine with having either an empty list or a list. I’m a bit dense, so I don’t really know what null would be in that list context.
cmo
Don’t see how this makes the default for embeds many confusing. What else could this value be? And a list of nothing is an empty list, no?
I get what you mean that it could say there is no value here, but that is if you think of the embed many field as the value. I think of the values as the things being embedded.
Using a list over nil probably saves us from nil checks all over the place. Would you prefer to check if it’s nil before you try to operate on it every time?







