Skip to content

Instantly share code, notes, and snippets.

@TrevorHinesley
Last active July 27, 2018 18:01
Show Gist options
  • Save TrevorHinesley/0098918e1f94c646398effbf40eb1d6a to your computer and use it in GitHub Desktop.
Save TrevorHinesley/0098918e1f94c646398effbf40eb1d6a to your computer and use it in GitHub Desktop.
Fast JSON API render simplifier
# Include this concern in your ApplicationController
# Must implement links_object and paginate_collection
module RenderJsonapi
extend ActiveSupport::Concern
included do
def render_jsonapi(*args)
options = args.extract_options!
collection = args.first
collection = paginate_collection(collection) if options[:paginate] == true
serializer_key = options[:serializer] || compute_collection_type(collection)
serializer_class_name = compute_serializer_name(serializer_key)
serializer_options = build_fast_jsonapi_options(options)
if options[:links] == true
serializer_options[:links] = links_object(collection)
end
serialized_collection = serializer_class_name.new(collection, serializer_options)
status = options[:status] || :ok
render jsonapi: serialized_collection, status: status
end
end
private
def compute_serializer_name(serializer_key)
return serializer_key unless serializer_key.is_a? Symbol
version = self.class.controller_path.split("/").first.upcase.to_s
serializer_name = serializer_key.to_s.classify + "Serializer"
(version + "::" + serializer_name).constantize
end
def compute_collection_type(collection)
if collection.is_a?(ActiveRecord::Relation)
# ActiveRecord::Relation has a #klass method to divulge the class of records it contains
collection_class = collection.klass
else
collection_class = collection.class
end
collection_class.base_class.name.to_sym
end
def links_object(collection)
# Generate your top-level links object here
end
def paginate_collection(collection)
# Implement your pagination here
end
def build_fast_jsonapi_options(options)
json_options = {
params: options[:params] || {},
meta: options[:meta] || {},
}
json_options[:params][:current_user] = current_user
includes = options[:include]
if includes.present?
json_options[:include] = includes_array(includes)
end
json_options
end
def includes_array(includes)
includes.is_a?(Array) ? includes : [includes]
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment