mongoid - using includes to select children objects in a 1..N referenced relationship

mongoid, ruby, ruby-on-rails

Solution

You can use scopes to achieve this, particular default scopes. So in your Post model, you can define your model such:

class Post
   belongs_to :tag
   default_scope includes(:tag)
end

That way whenever you do a query to get posts, like Blog.posts, mongoid will also generate a query to get all the tags associated with each post.

Problem

I have a scenario like this: ``` blog.posts ``` where each post belongs to another object, say Tag (in a belongs_to, has_many relationship), so I can do: ``` tag.posts ``` To prevent the N+1 problem, I want to be able to do blog.posts, but also grab each tag associated with each post, so that two queries are generated, one for the posts, and one for all the tags (based on each tag_id belonging to the post). I noticed in mongoid documentation I can do: ``` Post.includes(:tag).where(:blog_id: blog.id) ``` which will get me all posts belonging to a blog, and also getting each tag associated with the post and putting in the identity map (provided it is enabled). The problem is, I want to do: ``` blog.posts ``` and somehow redefine the query to do what I want above. Is there a way to do that? At the moment I'm mitigating this by defining an extension: ``` has_many :posts do def with_tags includes(:tag) end end ``` so that I do ``` blog.posts.with_tags ``` but I would prefer that ``` blog.posts ``` does the above by default. Cheers.

Original source