diff --git a/lib/fast_jsonapi/object_serializer.rb b/lib/fast_jsonapi/object_serializer.rb index c9476e9..06fcbf6 100644 --- a/lib/fast_jsonapi/object_serializer.rb +++ b/lib/fast_jsonapi/object_serializer.rb @@ -49,7 +49,7 @@ module FastJsonapi return serializable_hash unless @resource - serializable_hash[:data] = self.class.record_hash(@resource, @fieldsets[self.class.record_type.to_sym], @params) + serializable_hash[:data] = self.class.record_hash(@resource, @fieldsets[self.class.record_type.to_sym], @includes, @params) serializable_hash[:included] = self.class.get_included_records(@resource, @includes, @known_included_objects, @fieldsets, @params) if @includes.present? serializable_hash end @@ -61,7 +61,7 @@ module FastJsonapi included = [] fieldset = @fieldsets[self.class.record_type.to_sym] @resource.each do |record| - data << self.class.record_hash(record, fieldset, @params) + data << self.class.record_hash(record, fieldset, @includes, @params) included.concat self.class.get_included_records(record, @includes, @known_included_objects, @fieldsets, @params) if @includes.present? end diff --git a/lib/fast_jsonapi/relationship.rb b/lib/fast_jsonapi/relationship.rb index f8a9bfd..5f82843 100644 --- a/lib/fast_jsonapi/relationship.rb +++ b/lib/fast_jsonapi/relationship.rb @@ -34,12 +34,12 @@ module FastJsonapi @lazy_load_data = lazy_load_data end - def serialize(record, serialization_params, output_hash) + def serialize(record, included, serialization_params, output_hash) if include_relationship?(record, serialization_params) empty_case = relationship_type == :has_many ? [] : nil output_hash[key] = {} - unless lazy_load_data + unless (lazy_load_data && !included) output_hash[key][:data] = ids_hash_from_record_and_relationship(record, serialization_params) || empty_case end add_links_hash(record, serialization_params, output_hash) if links.present? diff --git a/lib/fast_jsonapi/serialization_core.rb b/lib/fast_jsonapi/serialization_core.rb index 7dd1b76..1c9a3bc 100644 --- a/lib/fast_jsonapi/serialization_core.rb +++ b/lib/fast_jsonapi/serialization_core.rb @@ -51,13 +51,14 @@ module FastJsonapi end end - def relationships_hash(record, relationships = nil, fieldset = nil, params = {}) + def relationships_hash(record, relationships = nil, fieldset = nil, includes_list = nil, params = {}) relationships = relationships_to_serialize if relationships.nil? relationships = relationships.slice(*fieldset) if fieldset.present? relationships = {} if fieldset == [] - relationships.each_with_object({}) do |(_k, relationship), hash| - relationship.serialize(record, params, hash) + relationships.each_with_object({}) do |(key, relationship), hash| + included = includes_list.present? && includes_list.include?(key) + relationship.serialize(record, included, params, hash) end end @@ -65,23 +66,23 @@ module FastJsonapi meta_to_serialize.call(record, params) end - def record_hash(record, fieldset, params = {}) + def record_hash(record, fieldset, includes_list, params = {}) if cached record_hash = Rails.cache.fetch(record.cache_key, expires_in: cache_length, race_condition_ttl: race_condition_ttl) do temp_hash = id_hash(id_from_record(record), record_type, true) temp_hash[:attributes] = attributes_hash(record, fieldset, params) if attributes_to_serialize.present? temp_hash[:relationships] = {} - temp_hash[:relationships] = relationships_hash(record, cachable_relationships_to_serialize, fieldset, params) if cachable_relationships_to_serialize.present? + temp_hash[:relationships] = relationships_hash(record, cachable_relationships_to_serialize, fieldset, includes_list, params) if cachable_relationships_to_serialize.present? temp_hash[:links] = links_hash(record, params) if data_links.present? temp_hash end - record_hash[:relationships] = record_hash[:relationships].merge(relationships_hash(record, uncachable_relationships_to_serialize, fieldset, params)) if uncachable_relationships_to_serialize.present? + record_hash[:relationships] = record_hash[:relationships].merge(relationships_hash(record, uncachable_relationships_to_serialize, fieldset, includes_list, params)) if uncachable_relationships_to_serialize.present? record_hash[:meta] = meta_hash(record, params) if meta_to_serialize.present? record_hash else record_hash = id_hash(id_from_record(record), record_type, true) record_hash[:attributes] = attributes_hash(record, fieldset, params) if attributes_to_serialize.present? - record_hash[:relationships] = relationships_hash(record, nil, fieldset, params) if relationships_to_serialize.present? + record_hash[:relationships] = relationships_hash(record, nil, fieldset, includes_list, params) if relationships_to_serialize.present? record_hash[:links] = links_hash(record, params) if data_links.present? record_hash[:meta] = meta_hash(record, params) if meta_to_serialize.present? record_hash @@ -150,7 +151,7 @@ module FastJsonapi known_included_objects[code] = inc_obj - included_records << serializer.record_hash(inc_obj, fieldsets[serializer.record_type], params) + included_records << serializer.record_hash(inc_obj, fieldsets[serializer.record_type], includes_list, params) end end end diff --git a/spec/lib/object_serializer_relationship_links_spec.rb b/spec/lib/object_serializer_relationship_links_spec.rb index e0d4848..e45f9d7 100644 --- a/spec/lib/object_serializer_relationship_links_spec.rb +++ b/spec/lib/object_serializer_relationship_links_spec.rb @@ -68,6 +68,24 @@ describe FastJsonapi::ObjectSerializer do end end + context "including lazy loaded relationships" do + before(:context) do + class LazyLoadingMovieSerializer < MovieSerializer + has_many :actors, lazy_load_data: true, links: { + related: :actors_relationship_url + } + end + end + + let(:serializer) { LazyLoadingMovieSerializer.new(movie, include: [:actors]) } + let(:actor_hash) { hash[:data][:relationships][:actors] } + + it "includes the :data key" do + expect(actor_hash).to be_present + expect(actor_hash).to have_key(:data) + end + end + context "relationship links defined by a method on the object" do before(:context) do class Movie diff --git a/spec/lib/serialization_core_spec.rb b/spec/lib/serialization_core_spec.rb index adf33df..0d8d011 100644 --- a/spec/lib/serialization_core_spec.rb +++ b/spec/lib/serialization_core_spec.rb @@ -52,7 +52,7 @@ describe FastJsonapi::ObjectSerializer do end it 'returns correct hash when record_hash is called' do - record_hash = MovieSerializer.send(:record_hash, movie, nil) + record_hash = MovieSerializer.send(:record_hash, movie, nil, nil) expect(record_hash[:id]).to eq movie.id.to_s expect(record_hash[:type]).to eq MovieSerializer.record_type expect(record_hash).to have_key(:attributes) if MovieSerializer.attributes_to_serialize.present?