defmodule User do
use Ecto.Schema
schema "users" do
field :name, :string
embeds_one :phones, Phone
end
end
defmodule Phone do
use Ecto.Schema
embedded_schema do
field :number, :string
field :country, :string
end
end
and
defmodule User do
use Ecto.Schema
schema "users" do
field :name, :string
field :phones, :map
end
end
In other words, what does the use of embeds_one with the embedded_schema allows me to do that I can’t by just defining a :map type in the schema?
With embeds_one, ecto will cast the data into a struct and also give it an ID (more useful for collections). With a map, it stays a map. One consequence is that structs have atom keys, whereas the map will have string keys (because of JSON serialization). A struct always has the same keys, whereas a map can have arbitrary keys. It is harder to use changesets on plain maps, because you must also specify the types of each field.
It’s possible to use @primary_key false on embedded schemas as well. But then the embeds_one macro would need to have :on_update option set. It’s useful when upgrading from plain maps to embeds.