Skip to content

Instantly share code, notes, and snippets.

@raihan2006i
Forked from UsamaAshraf/Gemfile
Created May 6, 2019 12:30
Show Gist options
  • Save raihan2006i/fe426462ccbe5f15dffbd5c7764ef0c4 to your computer and use it in GitHub Desktop.
Save raihan2006i/fe426462ccbe5f15dffbd5c7764ef0c4 to your computer and use it in GitHub Desktop.
N+1 Queries, Batch Loading and Active Model Serializers
# ...
# https://github.com/exAspArk/batch-loader
gem 'batch-loader'
class Post < ApplicationRecord
# ...
def get_author_lazily
BatchLoader.for(self).batch do |posts, batch_loader|
User.where(:_id.in => posts.pluck(:author_id)).each do |user|
# Modify the user through a given block, say, for serialization.
modified_user = block_given? ? yield(user) : user
batch_loader.call(posts.detect { |p| p.author_id == user._id.to_s }, modified_user)
end
end
end
# ...
end
class PostsController < ApplicationController
def index
# Can't do Post.includes(:author) beacuse the author (User object)
# is stored in an entirely different database: a MongoDB instance.
posts = Post.all
render json: posts
end
end
class PostSerializer < ActiveModel::Serializer
attributes :id, :title, :details, :author
def author
object.get_author_lazily do |author|
# Serialize the author after it has been loaded.
ActiveModelSerializers::SerializableResource.new(author).as_json[:user]
end
end
# ...
end
class User
include Mongoid::Document
include Mongoid::Timestamps
# ...
end
class UserSerializer < ActiveModel::Serializer
# ....
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment