module RailsUtil::JsonHelper

`RailsUtil::JsonHelper` contains helper methods for rendering JSON API responses

Public Instance Methods

json_collection(resource, **options) click to toggle source

Renders array of JSON objects, along with other options, or an empty array if the array contains no values @param [Array] resources array of resources @param [Symbol=>[Integer, String, Array]] options the key-value option pairs @return [Array] array of json objects

# File lib/rails_util/json_helper.rb, line 32
def json_collection(resource, **options)
  return render json: [], **options unless resource.any?
  json_with(resource, **options)
end
json_empty(**options) click to toggle source

Renders empty JSON object, along with other options @param [Symbol=>[Integer, String, Array]] options the key-value option pairs @return [Object] empty json object

# File lib/rails_util/json_helper.rb, line 40
def json_empty(**options)
  render json: {}, **options
end
json_error(nested_path_or_obj, message=nil, **options) click to toggle source

Renders JSON error response with `422` status, along with other options @param [String, Hash] nested_path_or_obj the key-value option pairs @param [String] message the message to include in the error object @param [Symbol=>[Integer, String, Array]] options the key-value option pairs @return [Object] json error object

# File lib/rails_util/json_helper.rb, line 49
def json_error(nested_path_or_obj, message=nil, **options)
  error_obj = set_nested_path(nested_path_or_obj, message)
  render(
    json: { errors: error_obj },
    status: :unprocessable_entity,
    **options
  )
end
json_success(path_or_obj, message=nil, **options) click to toggle source

Renders JSON success response, along with other options @param [String,Hash] path_or_obj the key-value option pairs @param [String=nil] message the message to include in the error object @param [Symbol=>[Integer, String, Array]] options the key-value option pairs @return [Object] json success object

# File lib/rails_util/json_helper.rb, line 63
def json_success(path_or_obj, message=nil, **options)
  render(
    json: set_nested_path(path_or_obj, message),
    **options
  )
end
json_with(resource, **options) click to toggle source

Renders JSON object, along with other options @param [Object] resource `ActiveRecord` resource @param [Symbol=>[Integer, String, Array]] options the key-value option pairs @return [Object] json object

# File lib/rails_util/json_helper.rb, line 10
def json_with(resource, **options)
  return json_empty(**options) unless resource
  root_key = resource.class.name.split('::').last.underscore

  return json_error(
    { root_key => map_base_to__error(resource.errors.messages) },
    **options
  ) if errors?(resource)

  return json_success(
    { root_key => {} },
    **options
  ) if destroyed?(resource)

  serialize_json_resource(resource, **options)
end
serialize_json_resource(resource, **options) click to toggle source

Renders serialized JSON resource @param [Object] resource `ActiveRecord` resource @param [Symbol=>[Integer, String, Array]] options the key-value option pairs @return [Object] json resource object @raise [MissingSerializerError] if the provided resource does not have a serializer

# File lib/rails_util/json_helper.rb, line 75
def serialize_json_resource(resource, **options)
  serializer_options = options[:serializer_options] || {}
  serializable_resource = ActiveModelSerializers::SerializableResource.new(
    resource,
    serializer_options.merge(scope: serialization_scope)
  )
  raise MissingSerializerError unless serializable_resource.serializer?
  serialized_obj = serializable_resource.serializer_instance.object
  type = options[:resource] || serialized_object_type(serialized_obj)

  data = { type: type, attributes: serializable_resource.serializer_instance }
  data[:additional_data] = options[:additional_data] if options && options[:additional_data]

  render json: { data: data }, **options
end

Private Instance Methods

destroyed?(resource) click to toggle source
# File lib/rails_util/json_helper.rb, line 107
def destroyed?(resource)
  resource.respond_to?(:destroyed?) && resource.destroyed?
end
errors?(resource) click to toggle source
# File lib/rails_util/json_helper.rb, line 103
def errors?(resource)
  resource.respond_to?(:errors) && resource.errors.any?
end
map_base_to__error(error_obj) click to toggle source
# File lib/rails_util/json_helper.rb, line 98
def map_base_to__error(error_obj)
  error_obj[:_error] = error_obj.delete(:base) if error_obj.key? :base
  error_obj
end
path_to_hash(path, value) click to toggle source
# File lib/rails_util/json_helper.rb, line 121
def path_to_hash(path, value)
  parts = (path.is_a?(String) ? path.split('.') : path).reverse
  initial = { parts.shift => value }
  parts.reduce(initial) { |a, e| { e => a } }
end
serialized_object_type(obj) click to toggle source
# File lib/rails_util/json_helper.rb, line 115
def serialized_object_type(obj)
  is_multiple = obj.try(:length) && obj.length.positive?
  type = is_multiple ? Util.underscored_class_name(obj.first).pluralize : Util.underscored_class_name(obj)
  type.split('/').first
end
set_nested(path, value, obj={}) click to toggle source
# File lib/rails_util/json_helper.rb, line 111
def set_nested(path, value, obj={})
  obj.deep_merge(path_to_hash(path, value))
end
set_nested_path(nested_path_or_obj, message) click to toggle source
# File lib/rails_util/json_helper.rb, line 93
def set_nested_path(nested_path_or_obj, message)
  return set_nested(nested_path_or_obj, message) if nested_path_or_obj.is_a? String
  nested_path_or_obj
end