Idiomatic way to make ecto schema validate has_many relation AND has at least one association?

If SchemaA has_many SchemaB, what is the typical approach to validate if at least one SchemaB is associated to SchemaA?

For instance if I do

SchemaA.changeset(schema_a)

I want the resulting %Ecto.Changeset{errors: ____} to show error related to this issue if no SchemaB is associated.

Thanks in advance!

Have you checked out Changeset.add_error? It should allow you to add whatever errors you like depending on the state of the changeset or underlying data if you use it in combination with get_field and/or get_change. So for example if you want to validate that on create at least one B will be associated you can do

changeset = 
  changeset
  |> preload(:bs)
  |> cast(params, [])
  |> cast_assoc([:bs], with: &B.changeset/2)

changeset = 
  changeset
  |> get_change(:bs)
  |> case do
    [] -> add_error(changeset, :bs, "is required") # this might need to be nil not sure
    _ -> changeset
  end
2 Likes

wow I think that is very clean and would work. Thank you!!