How to do a bunch of inserts, updates and deletes in a row?

I have a logic in my controller that I’m doing a bunch of inserts, updates or maybe deletes, if some conditions are met.
My phoenix is just a api interfacing with a React frontend. It’s sending to the api a array of subjects in this form: Parameters: %{"class_subject" => [%{"id" => 26, "professor_id" => 2, "remove" => true, "subject_id" => 801}, %{"professor_id" => 3, "subject_id" => 1}], "id" => "56"}

Here is a print of my function in class_subjects_controller.ex.

As you can see, when some keys or flags is present, the code proceeds properly. But my problem here is that I’m using Enum.each to iterate my array and this seems weird and wrong way to do it (operation in each class_subject in array). Additionally, the function is returning json just for the last operation realized, instead I would prefer a accumulated return of all operations executed (maybe a list of ids inserted, updated or deleted).

Thanks in advance for some ideas or solutions.

Ps: I’m a beginner with Elixir.

Can you please replace the screenshot of your code with a proper copy and pasted code block?


Also if you want to have a list of results of operations, try Enum.map/2 instead of Enum.each/2.

1 Like

So if your objective is to do the inserts and updates within one database transaction (as if all succeeds or all fails), you should look into Ecto.Multi:
https://hexdocs.pm/ecto/Ecto.Multi.html

If your objective is to make the inserts and updates quicker, in batches, you should look into Ecto.insert_all/3 instead: https://hexdocs.pm/ecto/Ecto.Repo.html#c:insert_all/3 (& related update_all).

Whatever you do, you will somehow need to iterate over the parameters, with something like Enum.map and transform those parameters to either lists of changesets to be inserted / updated, or list of Ecto.Multi operations you want to execute in transaction. There is no going around that but you can shift your mind to thinking to more functional manner. What it means is that you are currently thinking along the lines:

“I have some parameters, I will iterate over them and insert them or update in database”.

This is not functional thinking about the problem, and results in very procedural looking code too. You are relying on creating side-effects while you iterate over items to do the persistence for you. The functional way to approach the problem is:

“I have some parameters, I will transform them to something (like commands, changesets etc) and then send down to database for updates to happen”

This way you push the operation that creates side-effects to very last moment. Your data transforamtion logic is then purely functional, you just somehow need to persist the stuff and this can’t be pure operation of course. Result should be code that’s prettier and also simpler to debug in future.

4 Likes