4

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 ?

4

1 に答える 1

3

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
于 2013-03-25T04:56:03.860 に答える