From 4f576a1463cd8337e090c5b8d29766e38e54eaf8 Mon Sep 17 00:00:00 2001 From: Benedikt Deicke Date: Thu, 21 May 2015 16:35:35 +0200 Subject: [PATCH] Adjusts JsonApi adapter to serialize relationships in a nested `relationships` hash --- .../serializer/adapter/json_api.rb | 30 +++--- .../action_controller/json_api_linked_test.rb | 16 ++-- test/adapter/json_api/belongs_to_test.rb | 54 +++++------ test/adapter/json_api/collection_test.rb | 32 +++---- .../json_api/has_many_embed_ids_test.rb | 4 +- .../has_many_explicit_serializer_test.rb | 28 +++--- test/adapter/json_api/has_many_test.rb | 32 +++---- test/adapter/json_api/has_one_test.rb | 8 +- test/adapter/json_api/linked_test.rb | 96 +++++++++---------- 9 files changed, 150 insertions(+), 150 deletions(-) diff --git a/lib/active_model/serializer/adapter/json_api.rb b/lib/active_model/serializer/adapter/json_api.rb index f8bea380..8028a075 100644 --- a/lib/active_model/serializer/adapter/json_api.rb +++ b/lib/active_model/serializer/adapter/json_api.rb @@ -29,7 +29,7 @@ module ActiveModel end else @hash[:data] = attributes_for_serializer(serializer, @options) - add_resource_links(@hash[:data], serializer) + add_resource_relationships(@hash[:data], serializer) end @hash end @@ -41,18 +41,18 @@ module ActiveModel private - def add_links(resource, name, serializers) - resource[:links] ||= {} - resource[:links][name] ||= { linkage: [] } - resource[:links][name][:linkage] += serializers.map { |serializer| { type: serializer.type, id: serializer.id.to_s } } + def add_relationships(resource, name, serializers) + resource[:relationships] ||= {} + resource[:relationships][name] ||= { data: [] } + resource[:relationships][name][:data] += serializers.map { |serializer| { type: serializer.type, id: serializer.id.to_s } } end - def add_link(resource, name, serializer, val=nil) - resource[:links] ||= {} - resource[:links][name] = { linkage: nil } + def add_relationship(resource, name, serializer, val=nil) + resource[:relationships] ||= {} + resource[:relationships][name] = { data: nil } if serializer && serializer.object - resource[:links][name][:linkage] = { type: serializer.type, id: serializer.id.to_s } + resource[:relationships][name][:data] = { type: serializer.type, id: serializer.id.to_s } end end @@ -68,7 +68,7 @@ module ActiveModel serializers.each do |serializer| attrs = attributes_for_serializer(serializer, @options) - add_resource_links(attrs, serializer, add_included: false) + add_resource_relationships(attrs, serializer, add_included: false) @hash[:included].push(attrs) unless @hash[:included].include?(attrs) end @@ -128,19 +128,19 @@ module ActiveModel end end - def add_resource_links(attrs, serializer, options = {}) + def add_resource_relationships(attrs, serializer, options = {}) options[:add_included] = options.fetch(:add_included, true) serializer.each_association do |name, association, opts| - attrs[:links] ||= {} + attrs[:relationships] ||= {} if association.respond_to?(:each) - add_links(attrs, name, association) + add_relationships(attrs, name, association) else if opts[:virtual_value] - add_link(attrs, name, nil, opts[:virtual_value]) + add_relationship(attrs, name, nil, opts[:virtual_value]) else - add_link(attrs, name, association) + add_relationship(attrs, name, association) end end diff --git a/test/action_controller/json_api_linked_test.rb b/test/action_controller/json_api_linked_test.rb index 387640bc..559b2dd9 100644 --- a/test/action_controller/json_api_linked_test.rb +++ b/test/action_controller/json_api_linked_test.rb @@ -104,10 +104,10 @@ module ActionController "attributes" => { "name" => "Steve K." }, - "links" => { - "posts" => { "linkage" => [] }, - "roles" => { "linkage" => [{ "type" =>"roles", "id" => "1" }, { "type" =>"roles", "id" => "2" }] }, - "bio" => { "linkage" => nil } + "relationships" => { + "posts" => { "data" => [] }, + "roles" => { "data" => [{ "type" =>"roles", "id" => "1" }, { "type" =>"roles", "id" => "2" }] }, + "bio" => { "data" => nil } } }, { "id" => "1", @@ -117,8 +117,8 @@ module ActionController "description" => nil, "slug" => "admin-1" }, - "links" => { - "author" => { "linkage" => { "type" =>"authors", "id" => "1" } } + "relationships" => { + "author" => { "data" => { "type" =>"authors", "id" => "1" } } } }, { "id" => "2", @@ -128,8 +128,8 @@ module ActionController "description" => nil, "slug" => "colab-2" }, - "links" => { - "author" => { "linkage" => { "type" =>"authors", "id" => "1" } } + "relationships" => { + "author" => { "data" => { "type" =>"authors", "id" => "1" } } } } ] diff --git a/test/adapter/json_api/belongs_to_test.rb b/test/adapter/json_api/belongs_to_test.rb index 8a8aeef9..967b53e9 100644 --- a/test/adapter/json_api/belongs_to_test.rb +++ b/test/adapter/json_api/belongs_to_test.rb @@ -32,9 +32,9 @@ module ActiveModel end def test_includes_post_id - expected = { linkage: { type: "posts", id: "42" } } + expected = { data: { type: "posts", id: "42" } } - assert_equal(expected, @adapter.serializable_hash[:data][:links][:post]) + assert_equal(expected, @adapter.serializable_hash[:data][:relationships][:post]) end def test_includes_linked_post @@ -46,10 +46,10 @@ module ActiveModel title: 'New Post', body: 'Body', }, - links: { - comments: { linkage: [ { type: "comments", id: "1" } ] }, - blog: { linkage: { type: "blogs", id: "999" } }, - author: { linkage: { type: "authors", id: "1" } } + relationships: { + comments: { data: [ { type: "comments", id: "1" } ] }, + blog: { data: { type: "blogs", id: "999" } }, + author: { data: { type: "authors", id: "1" } } } }] assert_equal expected, @adapter.serializable_hash[:included] @@ -63,10 +63,10 @@ module ActiveModel attributes: { title: 'New Post' }, - links: { - comments: { linkage: [ { type: "comments", id: "1" } ] }, - blog: { linkage: { type: "blogs", id: "999" } }, - author: { linkage: { type: "authors", id: "1" } } + relationships: { + comments: { data: [ { type: "comments", id: "1" } ] }, + blog: { data: { type: "blogs", id: "999" } }, + author: { data: { type: "authors", id: "1" } } } }] assert_equal expected, @adapter.serializable_hash[:included] @@ -76,22 +76,22 @@ module ActiveModel serializer = PostSerializer.new(@anonymous_post) adapter = ActiveModel::Serializer::Adapter::JsonApi.new(serializer) - assert_equal({comments: { linkage: [] }, blog: { linkage: { type: "blogs", id: "999" } }, author: { linkage: nil }}, adapter.serializable_hash[:data][:links]) + assert_equal({comments: { data: [] }, blog: { data: { type: "blogs", id: "999" } }, author: { data: nil }}, adapter.serializable_hash[:data][:relationships]) end def test_include_type_for_association_when_different_than_name serializer = BlogSerializer.new(@blog) adapter = ActiveModel::Serializer::Adapter::JsonApi.new(serializer) - links = adapter.serializable_hash[:data][:links] + relationships = adapter.serializable_hash[:data][:relationships] expected = { writer: { - linkage: { + data: { type: "authors", id: "1" } }, articles: { - linkage: [ + data: [ { type: "posts", id: "42" @@ -103,7 +103,7 @@ module ActiveModel ] } } - assert_equal expected, links + assert_equal expected, relationships end def test_include_linked_resources_with_type_name @@ -117,10 +117,10 @@ module ActiveModel attributes: { name: "Steve K." }, - links: { - posts: { linkage: [] }, - roles: { linkage: [] }, - bio: { linkage: nil } + relationships: { + posts: { data: [] }, + roles: { data: [] }, + bio: { data: nil } } },{ id: "42", @@ -129,10 +129,10 @@ module ActiveModel title: "New Post", body: "Body" }, - links: { - comments: { linkage: [ { type: "comments", id: "1" } ] }, - blog: { linkage: { type: "blogs", id: "999" } }, - author: { linkage: { type: "authors", id: "1" } } + relationships: { + comments: { data: [ { type: "comments", id: "1" } ] }, + blog: { data: { type: "blogs", id: "999" } }, + author: { data: { type: "authors", id: "1" } } } }, { id: "43", @@ -141,10 +141,10 @@ module ActiveModel title: "Hello!!", body: "Hello, world!!" }, - links: { - comments: { linkage: [] }, - blog: { linkage: { type: "blogs", id: "999" } }, - author: { linkage: nil } + relationships: { + comments: { data: [] }, + blog: { data: { type: "blogs", id: "999" } }, + author: { data: nil } } } ] diff --git a/test/adapter/json_api/collection_test.rb b/test/adapter/json_api/collection_test.rb index 2426f439..f17285fa 100644 --- a/test/adapter/json_api/collection_test.rb +++ b/test/adapter/json_api/collection_test.rb @@ -33,10 +33,10 @@ module ActiveModel title: "Hello!!", body: "Hello, world!!" }, - links: { - comments: { linkage: [] }, - blog: { linkage: { type: "blogs", id: "999" } }, - author: { linkage: { type: "authors", id: "1" } } + relationships: { + comments: { data: [] }, + blog: { data: { type: "blogs", id: "999" } }, + author: { data: { type: "authors", id: "1" } } } }, { @@ -46,10 +46,10 @@ module ActiveModel title: "New Post", body: "Body" }, - links: { - comments: { linkage: [] }, - blog: { linkage: { type: "blogs", id: "999" } }, - author: { linkage: { type: "authors", id: "1" } } + relationships: { + comments: { data: [] }, + blog: { data: { type: "blogs", id: "999" } }, + author: { data: { type: "authors", id: "1" } } } } ] @@ -67,10 +67,10 @@ module ActiveModel attributes: { title: "Hello!!" }, - links: { - comments: { linkage: [] }, - blog: { linkage: { type: "blogs", id: "999" } }, - author: { linkage: { type: "authors", id: "1" } } + relationships: { + comments: { data: [] }, + blog: { data: { type: "blogs", id: "999" } }, + author: { data: { type: "authors", id: "1" } } } }, { @@ -79,10 +79,10 @@ module ActiveModel attributes: { title: "New Post" }, - links: { - comments: { linkage: [] }, - blog: { linkage: { type: "blogs", id: "999" } }, - author: { linkage: { type: "authors", id: "1" } } + relationships: { + comments: { data: [] }, + blog: { data: { type: "blogs", id: "999" } }, + author: { data: { type: "authors", id: "1" } } } } ] diff --git a/test/adapter/json_api/has_many_embed_ids_test.rb b/test/adapter/json_api/has_many_embed_ids_test.rb index 50f367c1..7dd132c7 100644 --- a/test/adapter/json_api/has_many_embed_ids_test.rb +++ b/test/adapter/json_api/has_many_embed_ids_test.rb @@ -26,13 +26,13 @@ module ActiveModel def test_includes_comment_ids expected = { - linkage: [ + data: [ { type: "posts", id: "1"}, { type: "posts", id: "2"} ] } - assert_equal(expected, @adapter.serializable_hash[:data][:links][:posts]) + assert_equal(expected, @adapter.serializable_hash[:data][:relationships][:posts]) end def test_no_includes_linked_comments diff --git a/test/adapter/json_api/has_many_explicit_serializer_test.rb b/test/adapter/json_api/has_many_explicit_serializer_test.rb index 4ff53728..2adb0eb5 100644 --- a/test/adapter/json_api/has_many_explicit_serializer_test.rb +++ b/test/adapter/json_api/has_many_explicit_serializer_test.rb @@ -30,13 +30,13 @@ module ActiveModel def test_includes_comment_ids expected = { - linkage: [ + data: [ { type: 'comments', id: '1' }, { type: 'comments', id: '2' } ] } - assert_equal(expected, @adapter.serializable_hash[:data][:links][:comments]) + assert_equal(expected, @adapter.serializable_hash[:data][:relationships][:comments]) end def test_includes_linked_data @@ -45,22 +45,22 @@ module ActiveModel { id: '1', type: 'comments', - links: { - post: { linkage: { type: 'posts', id: @post.id.to_s } } + relationships: { + post: { data: { type: 'posts', id: @post.id.to_s } } } }, { id: '2', type: 'comments', - links: { - post: { linkage: { type: 'posts', id: @post.id.to_s } } + relationships: { + post: { data: { type: 'posts', id: @post.id.to_s } } } }, { id: @author.id.to_s, type: "authors", - links: { - posts: { linkage: [ {type: "posts", id: @post.id.to_s } ] } + relationships: { + posts: { data: [ {type: "posts", id: @post.id.to_s } ] } } } ] @@ -70,26 +70,26 @@ module ActiveModel def test_includes_author_id expected = { - linkage: { type: "authors", id: @author.id.to_s } + data: { type: "authors", id: @author.id.to_s } } - assert_equal(expected, @adapter.serializable_hash[:data][:links][:author]) + assert_equal(expected, @adapter.serializable_hash[:data][:relationships][:author]) end def test_explicit_serializer_with_null_resource @post.author = nil - expected = { linkage: nil } + expected = { data: nil } - assert_equal(expected, @adapter.serializable_hash[:data][:links][:author]) + assert_equal(expected, @adapter.serializable_hash[:data][:relationships][:author]) end def test_explicit_serializer_with_null_collection @post.comments = [] - expected = { linkage: [] } + expected = { data: [] } - assert_equal(expected, @adapter.serializable_hash[:data][:links][:comments]) + assert_equal(expected, @adapter.serializable_hash[:data][:relationships][:comments]) end end end diff --git a/test/adapter/json_api/has_many_test.rb b/test/adapter/json_api/has_many_test.rb index da67dd37..a544fc80 100644 --- a/test/adapter/json_api/has_many_test.rb +++ b/test/adapter/json_api/has_many_test.rb @@ -33,9 +33,9 @@ module ActiveModel end def test_includes_comment_ids - expected = { linkage: [ { type: "comments", id: "1" }, { type: "comments", id: "2" } ] } + expected = { data: [ { type: "comments", id: "1" }, { type: "comments", id: "2" } ] } - assert_equal(expected, @adapter.serializable_hash[:data][:links][:comments]) + assert_equal(expected, @adapter.serializable_hash[:data][:relationships][:comments]) end def test_includes_linked_comments @@ -46,9 +46,9 @@ module ActiveModel attributes: { body: 'ZOMG A COMMENT' }, - links: { - post: { linkage: { type: "posts", id: "1" } }, - author: { linkage: nil } + relationships: { + post: { data: { type: "posts", id: "1" } }, + author: { data: nil } } }, { id: "2", @@ -56,9 +56,9 @@ module ActiveModel attributes: { body: 'ZOMG ANOTHER COMMENT' }, - links: { - post: { linkage: { type: "posts", id: "1" } }, - author: { linkage: nil } + relationships: { + post: { data: { type: "posts", id: "1" } }, + author: { data: nil } } }] assert_equal expected, @adapter.serializable_hash[:included] @@ -69,16 +69,16 @@ module ActiveModel expected = [{ id: "1", type: "comments", - links: { - post: { linkage: { type: "posts", id: "1" } }, - author: { linkage: nil } + relationships: { + post: { data: { type: "posts", id: "1" } }, + author: { data: nil } } }, { id: "2", type: "comments", - links: { - post: { linkage: { type: "posts", id: "1" } }, - author: { linkage: nil } + relationships: { + post: { data: { type: "posts", id: "1" } }, + author: { data: nil } } }] assert_equal expected, @adapter.serializable_hash[:included] @@ -94,9 +94,9 @@ module ActiveModel def test_include_type_for_association_when_different_than_name serializer = BlogSerializer.new(@blog) adapter = ActiveModel::Serializer::Adapter::JsonApi.new(serializer) - actual = adapter.serializable_hash[:data][:links][:articles] + actual = adapter.serializable_hash[:data][:relationships][:articles] expected = { - linkage: [{ + data: [{ type: "posts", id: "1" }] diff --git a/test/adapter/json_api/has_one_test.rb b/test/adapter/json_api/has_one_test.rb index 1172f058..195d5682 100644 --- a/test/adapter/json_api/has_one_test.rb +++ b/test/adapter/json_api/has_one_test.rb @@ -30,9 +30,9 @@ module ActiveModel end def test_includes_bio_id - expected = { linkage: { type: "bios", id: "43" } } + expected = { data: { type: "bios", id: "43" } } - assert_equal(expected, @adapter.serializable_hash[:data][:links][:bio]) + assert_equal(expected, @adapter.serializable_hash[:data][:relationships][:bio]) end def test_includes_linked_bio @@ -46,8 +46,8 @@ module ActiveModel content:"AMS Contributor", rating: nil }, - links: { - author: { linkage: { type: "authors", id: "1" } } + relationships: { + author: { data: { type: "authors", id: "1" } } } } ] diff --git a/test/adapter/json_api/linked_test.rb b/test/adapter/json_api/linked_test.rb index 271fb8a7..ff27fac8 100644 --- a/test/adapter/json_api/linked_test.rb +++ b/test/adapter/json_api/linked_test.rb @@ -59,10 +59,10 @@ module ActiveModel title: "Hello!!", body: "Hello, world!!" }, - links: { - comments: { linkage: [ { type: "comments", id: '1' }, { type: "comments", id: '2' } ] }, - blog: { linkage: { type: "blogs", id: "999" } }, - author: { linkage: { type: "authors", id: "1" } } + relationships: { + comments: { data: [ { type: "comments", id: '1' }, { type: "comments", id: '2' } ] }, + blog: { data: { type: "blogs", id: "999" } }, + author: { data: { type: "authors", id: "1" } } } }, { @@ -72,10 +72,10 @@ module ActiveModel title: "New Post", body: "Body" }, - links: { - comments: { linkage: [] }, - blog: { linkage: { type: "blogs", id: "999" } }, - author: { linkage: { type: "authors", id: "2" } } + relationships: { + comments: { data: [] }, + blog: { data: { type: "blogs", id: "999" } }, + author: { data: { type: "authors", id: "2" } } } } ], @@ -86,9 +86,9 @@ module ActiveModel attributes: { body: "ZOMG A COMMENT" }, - links: { - post: { linkage: { type: "posts", id: "10" } }, - author: { linkage: nil } + relationships: { + post: { data: { type: "posts", id: "10" } }, + author: { data: nil } } }, { id: "2", @@ -96,9 +96,9 @@ module ActiveModel attributes: { body: "ZOMG ANOTHER COMMENT", }, - links: { - post: { linkage: { type: "posts", id: "10" } }, - author: { linkage: nil } + relationships: { + post: { data: { type: "posts", id: "10" } }, + author: { data: nil } } }, { id: "1", @@ -106,10 +106,10 @@ module ActiveModel attributes: { name: "Steve K." }, - links: { - posts: { linkage: [ { type: "posts", id: "10" }, { type: "posts", id: "30" } ] }, - roles: { linkage: [] }, - bio: { linkage: { type: "bios", id: "1" } } + relationships: { + posts: { data: [ { type: "posts", id: "10" }, { type: "posts", id: "30" } ] }, + roles: { data: [] }, + bio: { data: { type: "bios", id: "1" } } } }, { id: "1", @@ -118,8 +118,8 @@ module ActiveModel content: "AMS Contributor", rating: nil }, - links: { - author: { linkage: { type: "authors", id: "1" } } + relationships: { + author: { data: { type: "authors", id: "1" } } } }, { id: "2", @@ -127,10 +127,10 @@ module ActiveModel attributes: { name: "Tenderlove" }, - links: { - posts: { linkage: [ { type: "posts", id:"20" } ] }, - roles: { linkage: [] }, - bio: { linkage: { type: "bios", id: "2" } } + relationships: { + posts: { data: [ { type: "posts", id:"20" } ] }, + roles: { data: [] }, + bio: { data: { type: "bios", id: "2" } } } }, { id: "2", @@ -139,8 +139,8 @@ module ActiveModel rating: nil, content: "Rails Contributor", }, - links: { - author: { linkage: { type: "authors", id: "2" } } + relationships: { + author: { data: { type: "authors", id: "2" } } } } ] @@ -167,10 +167,10 @@ module ActiveModel attributes: { name: "Steve K." }, - links: { - posts: { linkage: [ { type: "posts", id: "10"}, { type: "posts", id: "30" }] }, - roles: { linkage: [] }, - bio: { linkage: { type: "bios", id: "1" }} + relationships: { + posts: { data: [ { type: "posts", id: "10"}, { type: "posts", id: "30" }] }, + roles: { data: [] }, + bio: { data: { type: "bios", id: "1" }} } }, { id: "10", @@ -179,10 +179,10 @@ module ActiveModel title: "Hello!!", body: "Hello, world!!" }, - links: { - comments: { linkage: [ { type: "comments", id: "1"}, { type: "comments", id: "2" }] }, - blog: { linkage: { type: "blogs", id: "999" } }, - author: { linkage: { type: "authors", id: "1" } } + relationships: { + comments: { data: [ { type: "comments", id: "1"}, { type: "comments", id: "2" }] }, + blog: { data: { type: "blogs", id: "999" } }, + author: { data: { type: "authors", id: "1" } } } }, { id: "30", @@ -191,10 +191,10 @@ module ActiveModel title: "Yet Another Post", body: "Body" }, - links: { - comments: { linkage: [] }, - blog: { linkage: { type: "blogs", id: "999" } }, - author: { linkage: { type: "authors", id: "1" } } + relationships: { + comments: { data: [] }, + blog: { data: { type: "blogs", id: "999" } }, + author: { data: { type: "authors", id: "1" } } } } ] @@ -208,16 +208,16 @@ module ActiveModel spammy_post.related = [Spam::UnrelatedLink.new(id: 456)] serializer = SpammyPostSerializer.new(spammy_post) adapter = ActiveModel::Serializer::Adapter::JsonApi.new(serializer) - links = adapter.serializable_hash[:data][:links] + relationships = adapter.serializable_hash[:data][:relationships] expected = { related: { - linkage: [{ + data: [{ type: 'unrelated_links', id: '456' }] } } - assert_equal expected, links + assert_equal expected, relationships end def test_multiple_references_to_same_resource @@ -235,15 +235,15 @@ module ActiveModel title: "Hello!!", body: "Hello, world!!" }, - links: { + relationships: { comments: { - linkage: [{type: "comments", id: "1"}, {type: "comments", id: "2"}] + data: [{type: "comments", id: "1"}, {type: "comments", id: "2"}] }, blog: { - linkage: {type: "blogs", id: "999"} + data: {type: "blogs", id: "999"} }, author: { - linkage: {type: "authors", id: "1"} + data: {type: "authors", id: "1"} } } } @@ -268,9 +268,9 @@ module ActiveModel title: "Hello!!", body: "Hello, world!!" }, - links: { - comments: { linkage: [ { type: "comments", id: '1' }, { type: "comments", id: '2' } ] }, - author: { linkage: nil } + relationships: { + comments: { data: [ { type: "comments", id: '1' }, { type: "comments", id: '2' } ] }, + author: { data: nil } } } }