class Api::CollectionsController < ActionController::API
def show
collection = Collection.includes(snips: [:author, :code_blocks]).find(params[:id])
render json: CollectionSerializer.new(collection).as_json
end
end
class CollectionSerializer
def initialize(collection)
@collection = collection
end
def as_json
{
id: @collection.id,
title: @collection.title,
snips: @collection.snips.map do |s|
{
id: s.id,
title: s.title,
author: { id: s.author.id, nickname: s.author.nickname },
code_blocks: s.code_blocks.map { |cb| { name: cb.name, lang: cb.hljs_language } }
}
end
}
end
end
When rendering JSON, the serializer layer can silently trigger extra queries. Force “preload then serialize” so your JSON rendering path is deterministic. This pattern scales well in Rails APIs.