lib/jsonapi/resource_serializer.rb in jsonapi-resources-0.2.0 vs lib/jsonapi/resource_serializer.rb in jsonapi-resources-0.3.0.pre1
- old
+ new
@@ -25,40 +25,52 @@
# Converts a single resource, or an array of resources to a hash, conforming to the JSONAPI structure
def serialize_to_hash(source)
is_resource_collection = source.respond_to?(:to_ary)
- @linked_objects = {}
+ @included_objects = {}
requested_associations = parse_includes(@include)
process_primary(source, requested_associations)
- linked_objects = []
+ included_objects = []
primary_objects = []
- @linked_objects.each_value do |objects|
+ @included_objects.each_value do |objects|
objects.each_value do |object|
if object[:primary]
primary_objects.push(object[:object_hash])
else
- linked_objects.push(object[:object_hash])
+ included_objects.push(object[:object_hash])
end
end
end
primary_hash = {data: is_resource_collection ? primary_objects : primary_objects[0]}
- if linked_objects.size > 0
- primary_hash[:linked] = linked_objects
+ if included_objects.size > 0
+ primary_hash[:included] = included_objects
else
primary_hash
end
primary_hash
end
def serialize_to_links_hash(source, requested_association)
- {data: link_object(source, requested_association, true)}
+ if requested_association.is_a?(JSONAPI::Association::HasOne)
+ data = has_one_linkage(source, requested_association)
+ else
+ data = has_many_linkage(source, requested_association)
+ end
+
+ {
+ links: {
+ self: self_link(source, requested_association),
+ related: related_link(source, requested_association)
+ },
+ data: data
+ }
end
private
# Convert an array of associated objects to include along with the primary document in the form of
# ['comments','author','comments.tags','author.posts'] into a structure that tells what we need to include
@@ -93,21 +105,21 @@
id = resource.id
if already_serialized?(@primary_class_name, id)
set_primary(@primary_class_name, id)
end
- add_linked_object(@primary_class_name, id, object_hash(resource, requested_associations), true)
+ add_included_object(@primary_class_name, id, object_hash(resource, requested_associations), true)
end
else
resource = source
id = resource.id
# ToDo: See if this is actually needed
# if already_serialized?(@primary_class_name, id)
# set_primary(@primary_class_name, id)
# end
- add_linked_object(@primary_class_name, id, object_hash(source, requested_associations), true)
+ add_included_object(@primary_class_name, id, object_hash(source, requested_associations), true)
end
end
# Returns a serialized hash for the source model, with
def object_hash(source, requested_associations)
@@ -183,22 +195,22 @@
resource = source.send(name)
if resource
id = resource.id
associations_only = already_serialized?(type, id)
if include_linkage && !associations_only
- add_linked_object(type, id, object_hash(resource, ia[:include_related]))
+ add_included_object(type, id, object_hash(resource, ia[:include_related]))
elsif include_linked_children || associations_only
links_hash(resource, ia[:include_related])
end
end
elsif association.is_a?(JSONAPI::Association::HasMany)
resources = source.send(name)
resources.each do |resource|
id = resource.id
associations_only = already_serialized?(type, id)
if include_linkage && !associations_only
- add_linked_object(type, id, object_hash(resource, ia[:include_related]))
+ add_included_object(type, id, object_hash(resource, ia[:include_related]))
elsif include_linked_children || associations_only
links_hash(resource, ia[:include_related])
end
end
end
@@ -215,40 +227,57 @@
"#{@base_url}/#{formatted_module_path(source)}#{@route_formatter.format(source.class._type.to_s)}/#{source.id}"
end
def already_serialized?(type, id)
type = format_key(type)
- return @linked_objects.key?(type) && @linked_objects[type].key?(id)
+ return @included_objects.key?(type) && @included_objects[type].key?(id)
end
def format_route(route)
@route_formatter.format(route.to_s)
end
- def link_object_has_one(source, association)
- route = association.name
+ def self_link(source, association)
+ "#{self_href(source)}/links/#{format_route(association.name)}"
+ end
+ def related_link(source, association)
+ "#{self_href(source)}/#{format_route(association.name)}"
+ end
+
+ def has_one_linkage(source, association)
+ linkage = {}
+ linkage_id = foreign_key_value(source, association)
+ if linkage_id
+ linkage[:type] = format_route(association.type)
+ linkage[:id] = linkage_id
+ end
+ linkage
+ end
+
+ def has_many_linkage(source, association)
+ linkage = []
+ linkage_ids = foreign_key_value(source, association)
+ linkage_ids.each do |linkage_id|
+ linkage.append({type: format_route(association.type), id: linkage_id})
+ end
+ linkage
+ end
+
+ def link_object_has_one(source, association)
link_object_hash = {}
- link_object_hash[:self] = "#{self_href(source)}/links/#{format_route(route)}"
- link_object_hash[:resource] = "#{self_href(source)}/#{format_route(route)}"
- # ToDo: Get correct formatting figured out
- link_object_hash[:type] = format_route(association.type)
- link_object_hash[:id] = foreign_key_value(source, association)
+ link_object_hash[:self] = self_link(source, association)
+ link_object_hash[:related] = related_link(source, association)
+ link_object_hash[:linkage] = has_one_linkage(source, association)
link_object_hash
end
def link_object_has_many(source, association, include_linkage)
- route = association.name
-
link_object_hash = {}
- link_object_hash[:self] = "#{self_href(source)}/links/#{format_route(route)}"
- link_object_hash[:resource] = "#{self_href(source)}/#{format_route(route)}"
- if include_linkage
- # ToDo: Get correct formatting figured out
- link_object_hash[:type] = format_route(association.type)
- link_object_hash[:ids] = foreign_key_value(source, association)
- end
+ link_object_hash[:self] = self_link(source, association)
+ link_object_hash[:related] = related_link(source, association)
+ link_object_hash[:linkage] = has_many_linkage(source, association) if include_linkage
link_object_hash
end
def link_object(source, association, include_linkage = false)
if association.is_a?(JSONAPI::Association::HasOne)
@@ -271,26 +300,26 @@
end
# Sets that an object should be included in the primary document of the response.
def set_primary(type, id)
type = format_key(type)
- @linked_objects[type][id][:primary] = true
+ @included_objects[type][id][:primary] = true
end
# Collects the hashes for all objects processed by the serializer
- def add_linked_object(type, id, object_hash, primary = false)
+ def add_included_object(type, id, object_hash, primary = false)
type = format_key(type)
- unless @linked_objects.key?(type)
- @linked_objects[type] = {}
+ unless @included_objects.key?(type)
+ @included_objects[type] = {}
end
if already_serialized?(type, id)
if primary
set_primary(type, id)
end
else
- @linked_objects[type].store(id, {primary: primary, object_hash: object_hash})
+ @included_objects[type].store(id, {primary: primary, object_hash: object_hash})
end
end
def format_key(key)
@key_formatter.format(key)