Replacing embeds and returning to the view without saving to the database

I have a database object with an embeds_many that is defined as embeds_many :availability, Availability, on_replace: :delete. I am trying to replace it completely but putting new data with put_embed and returning the changeset to the view without saving it, but it is not working. I have this in my context:

def update(calendar, attrs) do
    calendar
    |> Calendar.changeset(attrs)
    |> Ecto.Changeset.put_embed(:availability, get_updated_availability())
end

and in the controller, I have something like

changeset = Calendars.update(calendar, calendar_params)
render(conn, "index.html", calendar: calendar, changeset: changeset)

when I try to process it, I get

%CombinaAi.Calendars.Availability{id: nil, weekday: nil, time_intervals: []}

which doesn’t render anything, but it works if I save it to the database before returning it to the view.

Is there a way to make this pipeline work without saving it to the database?

You can use Ecto.Changeset.apply_changes/1

But you should consider whether you want to show this data to the user if the update operation fails for any reason, i.e. bad data or database failure

1 Like

It worked as expected, thank you! I intend to generate some inputs dynamically in the form without saving anything, so it is safe. It would be better to do it in javascript (or maybe liveview?) but let me learn a little bit more about phoenix first :smile:

1 Like