How are joins in scopes in Rails 5.2 different from rails 5.1?

时光怂恿深爱的人放手 提交于 2019-12-06 12:02:29

Posting partial solution on how to preload last comment for a collection of posts

First you will need to have the following last_comment association:

class Post < ApplicationRecord
  has_many :comments, dependent: :destroy

  has_one :last_comment, -> { order(id: :desc) }, class_name: "Comment"
end

It works with preload and includes in Rails 5.2 and generates the following SQL queries:

Post.includes(:last_comment)

Post Load (0.2ms)  SELECT  "posts".* FROM "posts" LIMIT ?  [["LIMIT", 11]]
Comment Load (0.2ms)  SELECT "comments".* FROM "comments" WHERE "comments"."post_id" = ? ORDER BY "comments"."id" DESC  [["post_id", 1]]

The problem with this solution is that when I use joins it ignores association scope and generates the following SQL query:

Post.joins(:last_comment)

Post Load (0.2ms)  SELECT  "posts".* FROM "posts" INNER JOIN "comments" ON "comments"."post_id" = "posts"."id" LIMIT ?  [["LIMIT", 11]]

I was able to solve it changing the original last_comment association the following way:

class Post < ApplicationRecord
  has_many :comments, dependent: :destroy

  has_one :last_comment, -> {
    joins(:post)                               # <--- Note this change
    .where("
      comments.id = (
        SELECT MAX(comments.id) FROM comments
        WHERE comments.post_id = posts.id
      )"
    )
  }, class_name: "Comment"

  scope :with_last_comment, -> { joins(:last_comment) }
end

And now Post.with_last_comment generates the following SQL:

Post Load (0.3ms)  SELECT  "posts".* FROM "posts" INNER JOIN "comments" ON "comments"."post_id" = "posts"."id" INNER JOIN "posts" "posts_comments" ON "posts_comments"."id" = "comments"."post_id" AND (
      comments.id = (
        SELECT MAX(comments.id) FROM comments
        WHERE comments.post_id = posts.id
      )) LIMIT ?  [["LIMIT", 11]]

The question on how joins in Rails 5.2 are different from Rails 5.1 is still open

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!