Rails provides four different ways to load association data. In this blog we are going to look at each of those.
Preload loads the association data in a separate query.
This is how includes loads data in the default case.
Since preload always generates two sql we can’t use posts table in
where condition. Following query will result in an error.
With preload where clauses can be applied.
Includes loads the association data in a separate query just like preload.
However it is smarter than preload. Above we saw that preload failed for query User.preload(:posts).where("posts.desc='ruby is awesome'"). Let’s try same with includes.
As you can see includes switches from using two separate queries to creating a single LEFT OUTER JOIN to get the data. And it also applied the supplied condition.
So includes changes from two queries to a single query in some cases. By default for a simple case it will use two queries. Let’s say that for some reason you want to force a simple includes case to use a single query instead of two. Use references to achieve that.
In the above case a single query was done.
eager loading loads all association in a single query using LEFT OUTER JOIN.
This is exactly what includes does when it is forced to make a single query when where or order clause is using an attribute from posts table.
Joins brings association data using inner join.
In the above case no posts data is selected. Above query can also
produce duplicate result. To see it let’s create some sample data.
With the above sample data if we execute User.joins(:posts) then this is the result we get
We can avoid the duplication by using distinct .
Also if we want to make use of attributes from posts table then we need to select them.
Note that using joins means if you use user.posts then another query will be performed.