1
\$\begingroup\$

I have this model:

  schema "jobs" do
    field :name, :string
    has_many :shiptos, MosaicApi.ShipTo
  end

I want to update the shiptos associated with a job: there could be new shiptos, some deleted, and changes to existing ones. In the end I decided simply to delete the existing and replace with what is sent by the client. This is what I ended up with:

  def update(conn, %{"id" => id, "shiptos" => ship_tos}, _user) do
    current_job =
      Repo.one from j in Job,
                where: j.id == ^id,
                preload: :shiptos
    current_shiptos =
      Map.get(current_job, :shiptos)
      |> Enum.map(fn st -> st.id end)

    # IO.inspect(current_shiptos)
    new_shipto_ids =
      Enum.map(ship_tos,
        fn ship_to ->
          ShipToController.insert_one %{job_id: id, ship_to: ship_to}
        end)

    # IO.inspect(new_shipto_ids)
    case Enum.all?(new_shipto_ids, fn {res, _} -> res == :ok end) do
      true ->
        Enum.each(current_shiptos,
          fn id -> ShipToController.delete_one id end)

        ids =
          new_shipto_ids
          |> Enum.map(fn {_, shipto} -> shipto.id end)

        render(conn, "new_ids.json", ids: ids)
      false ->
        conn
        |> put_status(:unprocessable_entity)
        |> send_resp(:no_content, "")
    end
  end

It seems to work, but I don't feel it is very robust.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.