Leo Jiang
Leo Jiang

Reputation: 26075

Fetch records from multiple tables at once in Rails?

When I do something like the following, Rails queries the DB twice:

p = Post.find(1)
c = p.comments

The queries look like:

SELECT "posts".* from "posts" WHERE "posts"."id" = 1 LIMIT 1

SELECT "comments".* FROM "comments" WHERE "comments"."post_id" = 1

Is there a way to combine them into 1 query? Something like:

SELECT p.*, c.*
FROM comments c
JOIN (
  SELECT * FROM posts WHERE id = 1 LIMIT 1
) p ON p.id = c.post_id

And then have Rails split it into 2 types of records?

Upvotes: 0

Views: 1846

Answers (1)

spickermann
spickermann

Reputation: 106802

Ruby on Rails allows to eager loading associations to avoid too many database queries – usually, this is used to reduce the common N+1 query problem to just two queries. For example, the following query would make only two queries even to load all posts and comments and it builds the associations internally.

Post.includes(:comments)

But no there is no way to automatically reduce a query like the one in your question to just one query and deconstruct the query result internally into different objects again.

When the deconstruction part is not important then you can write

Post.select('posts.*, comments.*').joins(:comments).where(id: 1)

Note that you might need to rename columns in the select call if there are columns having the same name in both tables.

Upvotes: 4

Related Questions