Best practice in clearing an optional belongs_to relationship in LiveView?

I’m using inputs_for for the fields of a belongs_to relationship in a LiveView form. This works for updating individual values, but is there a way with this to remove the association? The best I can think of is to bubble up an event to my form_component asking it to add a change to the changeset to remove the association.

What You could do is add a virtual attribute (for example delete) and add a check in your changeset to see if it is set. Then just add a delete checkbox in the UI…

Something like this

  defp maybe_mark_for_deletion(%{data: %{id: nil}} = changeset), do: changeset
  defp maybe_mark_for_deletion(changeset) do
    if get_change(changeset, :delete),
      do: %{changeset | action: :delete},
      else: changeset
  end

# And use it like this...
def changeset(...) do
  ...
  |> maybe_mark_for_deletion()
end
1 Like

Nice, that’s a solid solution for existing associations. I’m stumped on how to handle about-to-be-added associations though. It seems like the parent changeset would need to inspect this :delete attribute to clear out the pending data?

Check this article: One-to-Many liveview form.

2 Likes

You might use another virtual field, temp_id to distinguish new from existing.

The solution is also valid for one to many, and the article seems to use the same technique.

My source is this article…
https://fullstackphoenix.com/tutorials/nested-model-forms-with-phoenix-liveview

This feels like the cleanest solution, but also one I was hoping to avoid. I wanted to make a self-contained component that I can drop in just like the other form components. But this requires any parent to implement several handlers to support the use of the component. But yeah I don’t see a cleaner way to do it.

Thanks everyone!