Ecto Changeset, LiveView and has_many relation validation


I have two models Parent and Child, and a Parent has_many Child. Then I have a LiveView form for a Parent and a user can add and remove Child clicking a button.

This is implemented using an Ecto.Changeset for a Parent model. When the form is changed, I receive all the params so I can build a new changeset and I render the form again. When the user clicks on “add a new Child”, I just append a Child Ecto.Changeset to my current Parent changeset in socket.assigns.

However, this behaviour is not perfect when I mark the Child relation as :required using Ecto.Changeset.cast_assoc/3. When a Parent is invalid because it doesn’t have Child and the user clicks on “Add a new Child”, I reuse my old changeset—because I don’t have all the params to rebuild—which is currently marked as invalid! So I render the form with the error message, but this is completely wrong and it isn’t true anymore. Until the user doesn’t modify an input in the form, I cannot rebuild the changeset correctly and update the errors.

I can try to handle this by myself—in fact, I have a lot of more models and hierarchy so it isn’t that easy—but I was wondering if there is a simpler way to do this.

Thanks in advance :slight_smile:

1 Like