Unable to understand docs around many-to-many ecto preload functions

Im trying to understand this section of the ecto documentation:

https://hexdocs.pm/ecto/Ecto.Query.html#preload/3-preload-functions

For many_to_many - the function receives the IDs of the parent association and it must return a tuple with the parent id as the first element and the association map or struct as the second. For example, if a post has many tags, when preloading the tags with a custom function, the function will receive a list of "post_ids" as the argument and it must return a tuple in the format of {post_id, tag}

By experimentation I’ve figured out that parent here refers to the post itself. Which leads to my first question.

Why does Repo.preload(my_post, tags: &my_custom_preloader/1) call my custom preloader with an array containing the id of my_post? When would it ever get more Ids?

Now to the second source of my confusion: the function will receive a list of "post_ids" as the argument and it must return a tuple in the format of {post_id, tag}

How do I go about transforming many post ids to one post id and one tag if the result somehow is to represent a many-to-many relationship?

2 Likes

Repo.preload can be called with a list of posts.

3 Likes

That makes sense. Something like

Repo.all(Post) |> Repo.preload(tags: &my_custom_preloader/1)

but with that confirmed, I’m even more confused how to return something meaningful if it has to be a tuple in the format of {post_id, tag}.

Wouldn’t it make more sense to return a list of tuples?

3 Likes

Welcome to the club :slight_smile:

I also had some difficulty in understanding them but after watching some videos from @AlchemistCamp I was able to get my ahead around many_to_many relations in Ecto :slight_smile:

I am not able to find which video I used on the time, but he has now a beginner series on Ecto and you can watch his video on many_to_many associations to see if you can understand them better, and while doing so you can take some video-notes here:

Screenshot from 2021-04-20 21-18-31

You can also watch the video directly on his website by following the links in my notes.

3 Likes

I face the same situation and What works for me is returning a list of tuple.

I guess author has mistable of saying it’s a tuple is because He think from perspective of single row in M2M table that sit in between.