Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Preload all Relationships

I have an ERM similar to this one:

--------     --------     --------
|ModelA|-----|ModelB|-----|ModelC|
--------     --------     --------

I get ModelA and its ModelBs with the following:

modela = Repo.get(ModelA,1)
modela = preload(modela, :modelb)

Now I can access ModelBs with modela.modelb. But how can I preload ModelC aswell? When I print my modelA, it says, that modelc is not loaded.

like image 568
0xAffe Avatar asked Dec 06 '22 19:12

0xAffe


2 Answers

You can pass a list to Repo.preload to load multiple associations. You can even pass a keyword list to preload nested associations. I also find it useful to load everything that I need in the query itself (those two options below are equivalent):

query = from m in ModelA, preload: [modelb: :modelc]
Repo.get(query, 1)

Repo.get(ModelA, 1) |> Repo.preload(modelb: :modelc)

You can also pass tuples with {association_name, query} for advanced preloding - especially useful in many associations to specify ordering.

You can read more of the documentation on preloads in the Ecto.Query.preload/3 docs

like image 85
michalmuskala Avatar answered Dec 14 '22 15:12

michalmuskala


Can't comment yet but you have to define the nested relationship in ModelA. See Ecto.Schema

has_one :model_c, through: [:model_b, :model_c]

like image 29
J_Tarasovic Avatar answered Dec 14 '22 15:12

J_Tarasovic