Updating embeded fields

I have just started working with embedded fields and am having a bit of trouble. In model Note, I have the following structure:

schema "notes" do
    use Timex.Ecto.Timestamps

    field :title, :string
    field :content, :string .. ETC ..
    embeds_one :settings, NoteSettings
    belongs_to :user, LookupPhoenix.User
    timestamps()
  end

Then in NoteSettings I have this:

embedded_schema do
    field :render_as, :string
    field :doc_type, :string
  end


  def set_defaults(note) do
     changeset = Ecto.Changeset.change(note)
     new_settings = %LookupPhoenix.NoteSettings{render_as: "mm", doc_type: "note"}
     changeset = Ecto.Changeset.put_embed(changeset, :settings, new_settings)
     Repo.update!(changeset)
  end

The foregoing code works fine – I can set the initial value of settings using set_defaults. But I fail when I try to update the settings with the following:

  def update_doc_type(note, value) do
    old_settings = note.settings
    new_settings = %LookupPhoenix.NoteSettings{old_settings | doc_type: value}
    changeset =
    note
    |> Ecto.Changeset.change
    |> Ecto.Changeset.put_embed(:settings, new_settings)
    Repo.update!(changeset)
  end

I’ve verified that (a) the new_settings are correct. However, the changeset is empty:

A. new_settings
%LookupPhoenix.NoteSettings{doc_type: "index",
 id: "ec1cb813-9384-48b5-8d52-38e31a897204", render_as: "mm"}
--
((In the above, `index` is new value.
========================
B. changeset
#Ecto.Changeset<action: nil, changes: %{}, errors: [],
 data: #LookupPhoenix.Note<>, valid?: true>

I’m stumpred!

Have you tried passing changeset to put_embed?

new_settings = Ecto.Changeset.change(old_settings, %{doc_type: value})

2 Likes

That was it! Thank you very much!!