How to I correctly use includes to avoid N + 1 queries in this situation:
I have a set of categories that can be nested (i.e., they form a tree). For example:
- Teaching
- Course 1
- Office Hours
- Lecture
- Course 2
- Office Hours
- Lecture
- Course 1
- Research
- Project 1
- Project 2
- Service
To set up this hierarchy, each Category record has parent_id as a foreign key.
This is my Rails model:
class Category < ApplicationRecord
belongs_to :user
belongs_to :parent, class_name: "Category", optional: true
has_many :children, class_name: "Category", foreign_key: "parent_id"
end
I access all the categories for a given user using
@categories = Category.includes(:children).where(user_id: user.id)
However, every call to @categories[i].children generates a new query.
How do I correctly use includes so that I can access each category's child categories without additional queries.
(I also tried @categories = Category.where(user_id: user.id).includes(:children) with no change in behavior.)
includesis typically used for eager loading another table. In this case you already have access to the table you're searching through,categories.What you could do is build out a Hash/Dictionary of categories which would require one call to your
categoriestable to generate the hash.Then in referencing your categories as
category_hash[:some_id]will give you whatever data you want to store in your hash...with O(1) time and no additional db queries.