From e6c4455dcb3d1abcbb17c4a4c3eccd376e5bd082 Mon Sep 17 00:00:00 2001 From: Logan Sears Date: Mon, 1 Aug 2022 21:07:32 -0600 Subject: [PATCH] Don't render relationships unless explicity requested in 'include' param (which fixes a bunch of bugs with it) --- lib/jsonapi/serializable/resource.rb | 9 +-- spec/renderer/relationship_spec.rb | 2 +- spec/resource/as_jsonapi_spec.rb | 89 +--------------------------- spec/resource/key_format_spec.rb | 17 +----- spec/resource/linkage_spec.rb | 17 ------ 5 files changed, 8 insertions(+), 126 deletions(-) diff --git a/lib/jsonapi/serializable/resource.rb b/lib/jsonapi/serializable/resource.rb index eccd74c..fbac504 100644 --- a/lib/jsonapi/serializable/resource.rb +++ b/lib/jsonapi/serializable/resource.rb @@ -45,8 +45,7 @@ def as_jsonapi(fields: nil, include: []) attrs = requested_attributes(fields).each_with_object({}) do |(k, v), h| h[k] = instance_eval(&v) end - rels = requested_relationships(fields) - .each_with_object({}) do |(k, v), h| + rels = requested_relationships(include).each_with_object({}) do |(k, v), h| h[k] = v.as_jsonapi(include.include?(k)) end links = link_blocks.each_with_object({}) do |(k, v), h| @@ -92,8 +91,10 @@ def requested_attributes(fields) end # @api private - def requested_relationships(fields) - @_relationships.select { |k, _| fields.nil? || fields.include?(k) } + def requested_relationships(includes) + @_relationships.select do |k, v| + v.instance_variable_get('@_include_linkage') || includes.include?(k) + end end # @api private diff --git a/spec/renderer/relationship_spec.rb b/spec/renderer/relationship_spec.rb index 7b1362f..608ea99 100644 --- a/spec/renderer/relationship_spec.rb +++ b/spec/renderer/relationship_spec.rb @@ -115,6 +115,6 @@ end end expect_any_instance_of(JSONAPI::Serializable::Relationship).to receive(:included?) - subject.render(user, class: { User: klass, Post: SerializablePost }) + subject.render(user, include: [:posts], class: { User: klass, Post: SerializablePost }) end end diff --git a/spec/resource/as_jsonapi_spec.rb b/spec/resource/as_jsonapi_spec.rb index 50f1fc4..281f358 100644 --- a/spec/resource/as_jsonapi_spec.rb +++ b/spec/resource/as_jsonapi_spec.rb @@ -18,11 +18,6 @@ attributes: { name: 'Lucas', address: '22 Ruby drive' - }, - relationships: { - posts: { - meta: { included: false } - } } } @@ -34,12 +29,7 @@ actual = resource.as_jsonapi(fields: [:posts]) expected = { type: :users, - id: 'foo', - relationships: { - posts: { - meta: { included: false } - } - } + id: 'foo' } expect(actual).to eq(expected) @@ -74,83 +64,6 @@ expect(actual).to eq(expected) end - it 'omits linkage data for non-included relationships with links' do - klass = Class.new(JSONAPI::Serializable::Resource) do - type 'users' - attribute :name - relationship :posts do - link :self do - "http://api.example.com/users/#{@object.id}/relationships/posts" - end - end - end - - resource = klass.new(object: user) - actual = resource.as_jsonapi - expected = { - type: :users, - id: 'foo', - attributes: { name: 'Lucas' }, - relationships: { - posts: { - links: { - self: 'http://api.example.com/users/foo/relationships/posts' - } - } - } - } - - expect(actual).to eq(expected) - end - - it 'omits linkage data for non-included relationships with meta' do - klass = Class.new(JSONAPI::Serializable::Resource) do - type 'users' - attribute :name - relationship :posts do - meta foo: 'bar' - end - end - - resource = klass.new(object: user) - actual = resource.as_jsonapi - expected = { - type: :users, - id: 'foo', - attributes: { name: 'Lucas' }, - relationships: { - posts: { - meta: { foo: 'bar' } - } - } - } - - expect(actual).to eq(expected) - end - - it 'omits linkage data for non-included relationships no links nor meta' do - klass = Class.new(JSONAPI::Serializable::Resource) do - type 'users' - attribute :name - relationship :posts - end - - resource = klass.new(object: user) - actual = resource.as_jsonapi - expected = { - type: :users, - id: 'foo', - attributes: { name: 'Lucas' }, - relationships: { - posts: { - meta: { included: false } - } - } - } - - expect(actual).to eq(expected) - end - it 'explicitly sets linkage data' do klass = Class.new(JSONAPI::Serializable::Resource) do type 'users' diff --git a/spec/resource/key_format_spec.rb b/spec/resource/key_format_spec.rb index f8ccb15..f0a56cb 100644 --- a/spec/resource/key_format_spec.rb +++ b/spec/resource/key_format_spec.rb @@ -34,22 +34,7 @@ expected = { type: :foo, id: 'bar', - attributes: { Name: nil, Address: nil }, - relationships: { - Posts: { - meta: { included: false } - }, - Author: { - meta: { included: false } - }, - Comments: { - meta: { included: false } - }, - Review: { - meta: { included: false } - } - } - + attributes: { Name: nil, Address: nil } } it { is_expected.to eq(expected) } diff --git a/spec/resource/linkage_spec.rb b/spec/resource/linkage_spec.rb index 21c222a..9ee9870 100644 --- a/spec/resource/linkage_spec.rb +++ b/spec/resource/linkage_spec.rb @@ -43,21 +43,4 @@ expect(actual).to eq(expected) end - - it 'does not include overriden linkage unless included' do - klass = Class.new(JSONAPI::Serializable::Resource) do - type 'users' - relationship :posts, class: SerializablePost do - linkage do - [{ type: :posts, id: '5' }] - end - end - end - - resource = klass.new(object: user, _class: inferrer) - actual = resource.as_jsonapi[:relationships][:posts] - expected = { meta: { included: false } } - - expect(actual).to eq(expected) - end end