重写活动记录查询

Rewrite acrive record query

我有型号 Issue has_many :comments、型号 Comment has_many :assets, as: :assetable, class_name: 'Comment::Asset' 和型号 Asset belongs_to :assetable, polymorphic: true

我需要获取特定问题的所有资产。 我的第一个实现如下:

comments = Comment.where(issue_id: issue.id).ids
assets = Asset.where(assetable_id: comments)

然而,它显然远非完美。我相信,这应该使用 joins 或类似的东西重写,但我没能全神贯注并找到解决方案。你会推荐什么?

您可以“手动”加入带有注释的资产 table,因为您不能急切地加载它们之间的多态关联:

Asset
  .joins('JOIN comments ON comments.id = assets.assetable_id')
  .where(comments: { issue_id: issue.id })

但是,如果确实不需要联接,where 加上 select 也可以解决问题:

Asset.where(assetable_id: Comment.where(issue_id: issue.id).select(:id))

请注意,由于使用 select(:id) 而不是 ids(它会立即从结果行中提取每个 ID),因此只执行了一个查询:

SELECT assets.*
FROM assets
WHERE assets.assetable_id IN (
  SELECT comments.id
  FROM comments WHERE
  comments.issue_id = ?
)