diff --git a/lib/oat/adapters/json_api.rb b/lib/oat/adapters/json_api.rb index 7431958..c8ca40b 100644 --- a/lib/oat/adapters/json_api.rb +++ b/lib/oat/adapters/json_api.rb @@ -71,7 +71,7 @@ def meta(key, value) def entity(name, obj, serializer_class = nil, context_options = {}, &block) ent = serializer_from_block_or_class(obj, serializer_class, context_options, &block) - if ent + if ent && !serializer.serialized?(name, ent.item.id) ent_hash = ent.to_hash _name = entity_name(name) entity_hash[_name.to_s.pluralize.to_sym] ||= [] @@ -80,8 +80,9 @@ def entity(name, obj, serializer_class = nil, context_options = {}, &block) end end - def entities(name, collection, serializer_class = nil, context_options = {}, &block) + def entities(name, collection, serializer_class = nil, context_options = nil, &block) return if collection.nil? || collection.empty? + context_options ||= {} _name = entity_name(name) link_name = _name.to_s.pluralize.to_sym data[:links][link_name] = [] @@ -89,7 +90,7 @@ def entities(name, collection, serializer_class = nil, context_options = {}, &bl collection.each do |obj| entity_hash[link_name] ||= [] ent = serializer_from_block_or_class(obj, serializer_class, context_options, &block) - if ent + if ent && !serializer.serialized?(link_name, ent.item.id) ent_hash = ent.to_hash data[:links][link_name] << ent_hash[:id] entity_hash[link_name] << ent_hash @@ -104,13 +105,19 @@ def entity_name(name) private :entity_name - def collection(name, collection, serializer_class = nil, context_options = {}, &block) + def collection(name, collection, serializer_class = nil, context_options = nil, &block) + context_options ||= {} @treat_as_resource_collection = true data[:resource_collection] = [] unless data[:resource_collection].is_a?(Array) collection.each do |obj| ent = serializer_from_block_or_class(obj, serializer_class, context_options, &block) - data[:resource_collection] << ent.to_hash if ent + if ent + unless serializer.serialized?(root_name, ent.item.id) + # serializer.set_serialized(root_name, ent.item.id) + data[:resource_collection] << ent.to_hash + end + end end end diff --git a/lib/oat/serializer.rb b/lib/oat/serializer.rb index adceb68..86e11a6 100644 --- a/lib/oat/serializer.rb +++ b/lib/oat/serializer.rb @@ -4,6 +4,10 @@ class Serializer class_attribute :_adapter, :logger + class << self + attr_accessor :type + end + def self.schema(&block) @schema = block if block_given? @schema || Proc.new{} @@ -20,11 +24,16 @@ def self.warn(msg) attr_reader :item, :context, :adapter_class, :adapter - def initialize(item, context = {}, _adapter_class = nil, parent_serializer = nil) - @item, @context = item, context + def initialize(item, context = nil, _adapter_class = nil, parent_serializer = nil) + @item = item + @context = context || {} @parent_serializer = parent_serializer @adapter_class = _adapter_class || self.class.adapter @adapter = @adapter_class.new(self) + if self.class.type + type(self.class.type) + end + @context[:_serialized_entities] ||= {} end def top @@ -51,6 +60,9 @@ def respond_to_missing?(method_name, include_private = false) def to_hash @to_hash ||= ( + if self.class.type + Array(item).each { |i| set_serialized(self.class.type, i.id) } + end instance_eval(&self.class.schema) adapter.to_hash ) @@ -65,5 +77,16 @@ def map_property(name) property name, value end + def set_serialized(type, id) + @context[:_serialized_entities][type] ||= {} + @context[:_serialized_entities][type][id] = true + end + + def serialized?(type, id) + h = @context[:_serialized_entities] + h = h[type] if h + h[id] if h + end + end end