mihai
mihai

Reputation: 38593

Rails duplicate sql query even with includes

I have trouble understanding why are two duplicate sql queries generated in this situation:

I have a Post which has_many :comments

post = Post.where(id: 4).includes(:comments).first

generates these sql statements:

SELECT "posts".* FROM "posts" WHERE "posts"."id" = 4 LIMIT 1
SELECT "comments".* FROM "comments" WHERE "comments"."post_id" IN (4)

Now:

comment = post.comments.first

(no sql - good)
However:

post = comment.post

generates the same sql:

SELECT "posts".* FROM "posts" WHERE "posts"."id" = 4 LIMIT 1

It seems like the objects are not bound internally. Is there a way I can do that manually to avoid the second sql ?

Upvotes: 5

Views: 521

Answers (1)

numbers1311407
numbers1311407

Reputation: 34072

Use inverse_of to specify the bi-directional relationship. From the docs:

Specifying the :inverse_of option on associations lets you tell Active Record about inverse relationships and it will optimise object loading.

It may look redundant for simple cases, but associations are 1-way definitions. Specifying inverse_of lets Rails know that the two relationships are inverse of one another, and solves problems like the one you're having.

# in post.rb
has_many :comments, :inverse_of => :post

# in comment.rb
belongs_to :post, :inverse_of => :comments

Upvotes: 4

Related Questions