Frontier Airlines and the Principle of Customer Surprise
medium.com3 pointsby rurabe0 comments
last_three_posts = Post.limit(3).order(created_at: :desc)
@posts = Comment.where(post_id: last_three_posts) class Comment
scope :with_vote_count, ->{ joins(:votes).select('comments.*').select('count(votes.*) as vote_count') }
end
class Post
has_many :comments
has_many :comments_with_vote_counts, ->{ with_vote_counts }, class_name: 'Comment'
end
# in controller
@posts = Post.includes(:comments_with_vote_counts).limit(3).order(:created_at: :desc)
# in view/serializer, posts and comments are both AR instances
@posts.each do |post|
post.comments.each do |comment|
comment.vote_count # => Integer
end
end
This should give you 2 queries, one to load the posts, then one to load the comments and vote counts for the relevant posts. Controller stays nice and slim and the complexity is delegated to sql via the join scope, without any other dependencies.