diff --git a/lib/fast_jsonapi/serialization_core.rb b/lib/fast_jsonapi/serialization_core.rb index 0cbdad0..9eeecb7 100644 --- a/lib/fast_jsonapi/serialization_core.rb +++ b/lib/fast_jsonapi/serialization_core.rb @@ -67,6 +67,8 @@ module FastJsonapi end def record_hash(record, fieldset, includes_list, params = {}) + includes_list = parse_includes_list(includes_list) + if cache_store_instance cache_opts = record_cache_options(cache_store_options, fieldset, includes_list, params) record_hash = cache_store_instance.fetch(record, **cache_opts) do @@ -154,6 +156,9 @@ module FastJsonapi # @param includes_list [List] to be parsed # @return [Hash] def parse_includes_list(includes_list) + return {} unless includes_list.present? + return includes_list if includes_list.is_a?(Hash) + includes_list.each_with_object({}) do |include_item, include_sets| include_base, include_remainder = include_item.to_s.split('.', 2) include_sets[include_base.to_sym] ||= Set.new @@ -193,7 +198,7 @@ module FastJsonapi known_included_objects << code - included_records << serializer.record_hash(inc_obj, fieldsets[record_type], includes_list, params) + included_records << serializer.record_hash(inc_obj, fieldsets[record_type], include_item.last, params) end end end diff --git a/spec/fixtures/actor.rb b/spec/fixtures/actor.rb index f212de1..c30bbbc 100644 --- a/spec/fixtures/actor.rb +++ b/spec/fixtures/actor.rb @@ -32,6 +32,14 @@ class ActorSerializer < UserSerializer ) do |object| object.movies end + + has_many( + :lazy_played_movies, + lazy_load_data: true, + serializer: :movie + ) do |object| + object.movies + end end class CamelCaseActorSerializer diff --git a/spec/fixtures/movie.rb b/spec/fixtures/movie.rb index f99af21..a9b621f 100644 --- a/spec/fixtures/movie.rb +++ b/spec/fixtures/movie.rb @@ -73,6 +73,13 @@ class MovieSerializer related: ->(obj) { obj.url(obj) } } ) + has_many( + :lazy_actors, + id_method_name: :uid, + lazy_load_data: true + ) do |object| + object.actors + end has_one( :creator, object_method_name: :owner, diff --git a/spec/integration/relationships_spec.rb b/spec/integration/relationships_spec.rb index f0585a8..c56b943 100644 --- a/spec/integration/relationships_spec.rb +++ b/spec/integration/relationships_spec.rb @@ -141,6 +141,35 @@ RSpec.describe JSONAPI::Serializer do ) end end + + context 'with lazy loading' do + let(:params) do + { include: ['lazy_actors.lazy_played_movies'] } + end + + it do + actors_rel = movie.actors.map { |a| { 'id' => a.uid, 'type' => 'actor' } } + + expect(serialized['data']).to have_relationship('lazy_actors').with_data(actors_rel) + + expect(serialized['included']).to include( + have_type('actor') + .and(have_id(movie.actors[0].uid)) + .and( + have_relationship('lazy_played_movies').with_data( + [{ + 'id' => movie.actors[0].movies[0].id, + 'type' => 'movie' + }] + ) + ) + ) + + expect(serialized['included']).to include( + have_type('movie').and(have_id(movie.actors[0].movies[0].id)) + ) + end + end end end end