0.0
Low commit activity in last 3 years
No release in over a year
load top n records for each group
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
 Dependencies

Development

Runtime

 Project Readme

TopNLoader

When you need top 5 sub-records for each record

posts = Post.limit(10).to_a

Without TopNLoader: N+1 queries

posts = Post.limit(10)
render json: posts.map do |post|
  {
    title: post.title,
    comments: post.comments.order(id: :desc).limit(5)
  }
end

With TopNLoader: Only 2 queries

# One query here
posts = Post.limit(10).to_a
post_ids = posts.map(&:id)
# ANd just one query to load each comments(limit:5) for all posts
top5s = TopNLoader.load_associations Post, posts_ids, :comments, order: :desc, limit: 5
render json: posts.map do |post|
  {
    title: post.title,
    comments: top5s[post.id]
  }
end

Usage

# Gemfile
gem 'top_n_loader'
TopNLoader.load_associations(ParentModel, ids, relation_name, limit:, order: nil)
# limit: >=0
# order: :asc, :desc, {order_column: (:asc or :desc)}

# will return the results below with a single query
records = ParentModel.find(ids).map do |record|
  [record.id, record.send(relation_name).order(order).take(limit)]
end.to_h
TopNLoader.load_groups(YourModel, group_column, group_values, limit:, order: nil, condition: nil)
# limit: >=0
# order: :asc, :desc, {order_column: (:asc or :desc)}
# condition: 'name is null', ['name = ?', 'jack'], { age: (1..10), name: { not: 'jack' }}

# will return the results below with a single query
records = YourModel.where(condition).where(group_column => group_values).order(order)
records.group_by(&group_column).transform_values { |list| list.take(limit) }