How to change an embed_one of regular schema in an embedded_schema

I have an embedded_schema with an embeds_one in it tied to a regular schema.

embedded_schema do
  embeds_one :foo, Foo, on_replace: :update
end

When a use changes the “foo” from a option input on my form I need to update the embed, but everything I try gives an error.

put_embed(:foo, foo)

Gives me the old:

** (RuntimeError) you have set that the relation :foil of Nai.Aperture.Quote
has `:on_replace` set to `:update` but you are giving it a struct/
changeset to put_assoc/put_change. ...

If you indeed want to replace the existing :substance, you have
to change the foreign key field directly.

I tried:

put_embed(:foo, Map.from_struct(foo) |> Map.drop([:__meta__]))

But then I get the same error further down because my regular scheme (Foo) has a belongs_to in it. So now I’m to the point that I have to recurse my struct and convert every sub-struct to a map?

I must be doing something wrong. I’m not persisting to a database, rather just saving these as JSON files, though the regular schema struct is queried from a database.

Why is this :foil and not :foo?

Oops. It should be :foo – it is :foil in may actual program, I changed it to :foo for the example.

Try on_replace: :delete. This is what I always use for embeds since they are coming from forms and I always just want it to take the new thing wholesale. I’ve never use :update (for embeds) so not sure of the scenario where it is useful.

1 Like

Doh! That didn’t even occur to me – seeing that it “must be used carefully” (the documentation for on_replace leaves something to be desired).

Anyway, that did the trick! Thank you.

1 Like