I’d probably use an ecto multi to insert the flux and create relationships between it and some magnets inside a single database transaction.
Adapted from Is there are way to bulk insert join records of a many-to-many relationship with Ecto?
# in the module containing your business logic
# here I suppose that the magnets already exist
# and we only need to associate them with the
# created flux
@spec create_flux(%{(String.t | atom) => term}, [magnet_id :: pos_integer]) :: {:ok, %Flux{}} | {:error, Ecto.Changeset.t}
def create_flux(flux_attrs, magnet_ids) do
alias Ecto.Multi
flux_changeset = Flux.changeset(%Flux{}, flux_attrs)
Multi.new()
|> Multi.insert(:flux, flux_changeset)
|> Multi.run(:magnet_relationships, fn %{flux: %Flux{id: flux_id}} ->
# prepare relationships to be inserted into the many-to-many table
relationships = Enum.map(magnet_ids, fn magnet_id ->
%{magnet_id: magnet_id, flux_id: flux_id}
end)
# https://hexdocs.pm/ecto/Ecto.Repo.html#c:insert_all/3
{:ok, Repo.insert_all("magnets_fluxes", relationships)}
end)
|> Repo.transaction()
|> case do
{:ok, %{flux: flux}} -> {:ok, flux}
{:error, :flux, changeset, _changes} -> {:error, changeset}
end
end
Used like this
flux_attrs = %{title: "a flux", description: "a flux"}
magnet_ids = [1, 2, 3] # I suppose these already exist in the database
create_flux(flux_attrs, magnet_ids)