Hello everyone,
TL;DR: How to get a changeset with only embeds data?
I have some trouble understanding how cast_embed should work…
Let’s say I have the following “parent” schema:
schema "account" do
field :email, :string
....
embeds_one :user, User, on_replace: :delete
end
And the following (simplified) embedded schema and changeset for a user (also a JSONB in postgres):
@primary_key false
embedded_schema do
field :firstname, :string
field :lastname, :string
end
def changeset(%User{} = user, attrs) do
user
|> cast(attrs, [:firstname, :lastname])
|> validate_required([:firstname, :lastname])
end
Now I’m using multi-steps form, so at one moment I only want to have a changeset for that embed only, so I have the following dedicated changeset for an Account:
def user_changeset(account, attrs) do
account
|> cast(attrs, [])
|> cast_embed(:user)
|> validate_required([:user])
end
I’m expecting with the following input to have an invalid changeset:
iex> some_account
%Account{
email: "email@example.com,"
user: %User{
firstname: nil,
lastname: nil
}
}
iex> chgst = Account.user_changeset(some_account,%{})
#Ecto.Changeset<action: nil, changes: %{}, errors: [], data: #Account<>, valid?: true>
However, since the user has no firstname and lastname, I’m expecting that the changeset is invalid.
What am I missing?
If I include the :user
in the cast
:
def user_changeset(account, attrs) do
account
|> cast(attrs, [:user]) # <--- Here
|> cast_embed(:user)
|> validate_required([:user])
end
I got an error that casting embeds with cast/4 for :user field is not supported, use cast_embed/3 instead.
But this is what I’m doing…
I’m even wanting to do a similar embed-only changeset for another embeds_many :members
which will be an array this time…
Thank you very much…