From 2d21a8e83fa537ad3b5ea0fd9e961c781ff85cbd Mon Sep 17 00:00:00 2001 From: Guillermo Iguaran Date: Fri, 31 Oct 2014 01:54:13 -0500 Subject: [PATCH] Add type when association name is different than objects type --- .../serializer/adapter/json_api.rb | 23 ++++++++++++++++--- test/adapter/json_api/belongs_to_test.rb | 9 ++++++++ test/adapter/json_api/has_many_test.rb | 11 ++++++++- test/fixtures/poro.rb | 8 +++++++ 4 files changed, 47 insertions(+), 4 deletions(-) diff --git a/lib/active_model/serializer/adapter/json_api.rb b/lib/active_model/serializer/adapter/json_api.rb index f5ff71285..de0f3f83e 100644 --- a/lib/active_model/serializer/adapter/json_api.rb +++ b/lib/active_model/serializer/adapter/json_api.rb @@ -34,8 +34,18 @@ def serializable_hash(options = {}) end def add_links(name, serializers, options) - @hash[@root][:links][name] ||= [] - @hash[@root][:links][name] += serializers.map{|serializer| serializer.id.to_s } + if serializers.first + type = serializers.first.object.class.to_s.underscore.pluralize + end + if name.to_s == type || !type + @hash[@root][:links][name] ||= [] + @hash[@root][:links][name] += serializers.map{|serializer| serializer.id.to_s } + else + @hash[@root][:links][name] ||= {} + @hash[@root][:links][name][:type] = type + @hash[@root][:links][name][:ids] ||= [] + @hash[@root][:links][name][:ids] += serializers.map{|serializer| serializer.id.to_s } + end unless options[:embed] == :ids @hash[:linked][name] ||= [] @@ -45,7 +55,14 @@ def add_links(name, serializers, options) def add_link(name, serializer, options) if serializer - @hash[@root][:links][name] = serializer.id.to_s + type = serializer.object.class.to_s.underscore + if name.to_s == type || !type + @hash[@root][:links][name] = serializer.id.to_s + else + @hash[@root][:links][name] ||= {} + @hash[@root][:links][name][:type] = type + @hash[@root][:links][name][:id] = serializer.id.to_s + end unless options[:embed] == :ids plural_name = name.to_s.pluralize.to_sym diff --git a/test/adapter/json_api/belongs_to_test.rb b/test/adapter/json_api/belongs_to_test.rb index 58a0f6998..0db303a68 100644 --- a/test/adapter/json_api/belongs_to_test.rb +++ b/test/adapter/json_api/belongs_to_test.rb @@ -15,6 +15,9 @@ def setup @comment.post = @post @post.author = @author @anonymous_post.author = nil + @blog = Blog.new(id: 1, name: "My Blog!!") + @blog.writer = @author + @blog.articles = [@post, @anonymous_post] @serializer = CommentSerializer.new(@comment) @adapter = ActiveModel::Serializer::Adapter::JsonApi.new(@serializer) @@ -34,6 +37,12 @@ def test_include_nil_author assert_equal({comments: [], author: nil}, adapter.serializable_hash[:posts][:links]) end + + def test_include_type_for_association_when_is_different_than_name + serializer = BlogSerializer.new(@blog) + adapter = ActiveModel::Serializer::Adapter::JsonApi.new(serializer) + assert_equal({type: "author", id: "1"}, adapter.serializable_hash[:blogs][:links][:writer]) + end end end end diff --git a/test/adapter/json_api/has_many_test.rb b/test/adapter/json_api/has_many_test.rb index 17c9c17de..2f74195f0 100644 --- a/test/adapter/json_api/has_many_test.rb +++ b/test/adapter/json_api/has_many_test.rb @@ -7,13 +7,16 @@ class JsonApi class HasManyTest < Minitest::Test def setup @author = Author.new(id: 1, name: 'Steve K.') - @post = Post.new(title: 'New Post', body: 'Body') + @post = Post.new(id: 1, title: 'New Post', body: 'Body') @first_comment = Comment.new(id: 1, body: 'ZOMG A COMMENT') @second_comment = Comment.new(id: 2, body: 'ZOMG ANOTHER COMMENT') @post.comments = [@first_comment, @second_comment] @first_comment.post = @post @second_comment.post = @post @post.author = @author + @blog = Blog.new(id: 1, name: "My Blog!!") + @blog.writer = @author + @blog.articles = [@post] @serializer = PostSerializer.new(@post) @adapter = ActiveModel::Serializer::Adapter::JsonApi.new(@serializer) @@ -29,6 +32,12 @@ def test_includes_linked_comments {id: "2", body: 'ZOMG ANOTHER COMMENT'} ], @adapter.serializable_hash[:linked][:comments]) end + + def test_include_type_for_association_when_is_different_than_name + serializer = BlogSerializer.new(@blog) + adapter = ActiveModel::Serializer::Adapter::JsonApi.new(serializer) + assert_equal({type: "posts", ids: ["1"]}, adapter.serializable_hash[:blogs][:links][:articles]) + end end end end diff --git a/test/fixtures/poro.rb b/test/fixtures/poro.rb index ce5f345a2..77e3506fb 100644 --- a/test/fixtures/poro.rb +++ b/test/fixtures/poro.rb @@ -38,6 +38,7 @@ class ProfileSerializer < ActiveModel::Serializer Post = Class.new(Model) Comment = Class.new(Model) Author = Class.new(Model) +Blog = Class.new(Model) PostSerializer = Class.new(ActiveModel::Serializer) do attributes :title, :body, :id @@ -58,3 +59,10 @@ class ProfileSerializer < ActiveModel::Serializer has_many :posts, embed: :ids end + +BlogSerializer = Class.new(ActiveModel::Serializer) do + attributes :id, :name + + belongs_to :writer + has_many :articles +end