Home > Software design >  Rewrite acrive record query
Rewrite acrive record query

Time:12-29

I have model Issue that has_many :comments, model Comment that has_many :assets, as: :assetable, class_name: 'Comment::Asset', and model Asset that belongs_to :assetable, polymorphic: true

I need to get all the assets of the particular Issue. My firt implementation is as following:

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

However, it is obviously far from perfect. I believe, that this sould be rewritten using joins or something like this, but I fail to wrap my head around it and find a solution. What would you recommend?

CodePudding user response:

You can "manually" join the assets table with comments, as you cannot eagerly load the polymorphic association between them:

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

However if a join isn't really needed, where plus select do the trick as well:

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

Notice there only one query is performed due to the select(:id) usage instead of ids (which extracts at once every id from the resulting rows):

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