When retrieving an object from the DB that references another object in the DB, we have to send load_association! to the mapper to convert the reference object into its actual value. When retrieving individual 1:1-associated objects, this is fine, but the current implementation results in N+1 queries. We need a way to load entire sets of objects.
Use cases
A forum topic with many posts.
Currently, we load the topic, then send queries for each post object. We should be able to fire off something like a mapper.select { id.in? posts.map(&:id) } call. Something like this:
mapper.load_association! topic, :posts`
In this case, the posts object is an array, so we detect that and run with it.
List of users that each have a profile object.
Each user has a 1:1 association with a profile object.
mapper.load_association! users, :profile
In this case, the first parameter is the array. We could hold a hash-like object that uses the classes of the referenced objects as keys and the IDs as an array of values. This wouldn't necessarily be a single query, but would allow users to store objects that weren't all the same class. We would use the minimum number of queries necessary, which would always be the number of distinct classes of objects used for that particular attribute in that particular set of objects.
When retrieving an object from the DB that references another object in the DB, we have to send
load_association!
to the mapper to convert the reference object into its actual value. When retrieving individual 1:1-associated objects, this is fine, but the current implementation results in N+1 queries. We need a way to load entire sets of objects.Use cases
A forum topic with many posts.
Currently, we load the topic, then send queries for each post object. We should be able to fire off something like a
mapper.select { id.in? posts.map(&:id) }
call. Something like this:In this case, the
posts
object is an array, so we detect that and run with it.List of users that each have a profile object.
Each user has a 1:1 association with a profile object.
In this case, the first parameter is the array. We could hold a hash-like object that uses the classes of the referenced objects as keys and the IDs as an array of values. This wouldn't necessarily be a single query, but would allow users to store objects that weren't all the same class. We would use the minimum number of queries necessary, which would always be the number of distinct classes of objects used for that particular attribute in that particular set of objects.
Example:
{ UserProfile => [1, 2, 3], AdminProfile => [4, 5, 6] }
{ Profile => [1, 2, 3, 4, 5, 6] }
In the first example, we must use multiple queries, but the second example would only be one. Here's some pseudocode:
Articles containing lists of tags
The ActiveRecord
has_and_belongs_to_many
association.This would maybe need to be done using some sort of identity map? I'm not sure. I'll plug away at it soon.