diff --git a/lib/fast_jsonapi/serialization_core.rb b/lib/fast_jsonapi/serialization_core.rb index 4931fa7..42bff29 100644 --- a/lib/fast_jsonapi/serialization_core.rb +++ b/lib/fast_jsonapi/serialization_core.rb @@ -66,6 +66,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 @@ -153,6 +155,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 diff --git a/spec/fixtures/actor.rb b/spec/fixtures/actor.rb index f85120a..149cb63 100644 --- a/spec/fixtures/actor.rb +++ b/spec/fixtures/actor.rb @@ -31,6 +31,14 @@ class ActorSerializer < UserSerializer ) do |object| object.movies end + + has_many( + :lazy_played_movies, + serializer: :movie + ) do |object| + object.movies + end + end class CamelCaseActorSerializer diff --git a/spec/fixtures/movie.rb b/spec/fixtures/movie.rb index 3156443..59ae756 100644 --- a/spec/fixtures/movie.rb +++ b/spec/fixtures/movie.rb @@ -72,6 +72,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