From 6bb4501f67fe89cdb27537a71d8623178d9e5b63 Mon Sep 17 00:00:00 2001 From: Tema Bolshakov Date: Fri, 29 Aug 2014 11:37:27 +0400 Subject: [PATCH] JsonApi adapter: serialize association --- .../serializer/adapter/json_api_adapter.rb | 36 +++++++++++++------ test/adapter/json_api/belongs_to_test.rb | 29 +++++++++++++++ test/adapter/json_api/has_many.rb | 34 ++++++++++++++++++ test/adapter/json_api_adapter_test.rb | 26 -------------- 4 files changed, 88 insertions(+), 37 deletions(-) create mode 100644 test/adapter/json_api/belongs_to_test.rb create mode 100644 test/adapter/json_api/has_many.rb delete mode 100644 test/adapter/json_api_adapter_test.rb diff --git a/lib/active_model/serializer/adapter/json_api_adapter.rb b/lib/active_model/serializer/adapter/json_api_adapter.rb index d82fdd7f..0a5ce947 100644 --- a/lib/active_model/serializer/adapter/json_api_adapter.rb +++ b/lib/active_model/serializer/adapter/json_api_adapter.rb @@ -3,19 +3,33 @@ module ActiveModel class Adapter class JsonApiAdapter < Adapter def serializable_hash(options = {}) - hash = serializer.attributes + @hash = serializer.attributes - associations = serializer.associations(only: [:id]).each_with_object({}) do |(attr, value), h| - h[attr] = case value - when ActiveModel::Serializer::ArraySerializer - value.map(&:id) - when ActiveModel::Serializer - # process belongs_to association - else - # what? - end + serializer.associations.each do |name, association| + @hash[:links] ||= {} + @hash[:linked] ||= {} + if association.respond_to?(:each) + add_links(name, association) + else + add_link(name, association) + end end - hash.merge(associations) + @hash + end + + def add_links(name, serializers) + @hash[:links][name] ||= [] + @hash[:linked][name] ||= [] + @hash[:links][name] += serializers.map(&:id) + @hash[:linked][name] += serializers.map(&:attributes) + end + + def add_link(name, serializer) + plural_name = name.to_s.pluralize.to_sym + @hash[:linked][plural_name] ||= [] + + @hash[:links][name] = serializer.id + @hash[:linked][plural_name].push serializer.attributes end end end diff --git a/test/adapter/json_api/belongs_to_test.rb b/test/adapter/json_api/belongs_to_test.rb new file mode 100644 index 00000000..d4beddf9 --- /dev/null +++ b/test/adapter/json_api/belongs_to_test.rb @@ -0,0 +1,29 @@ +require 'test_helper' + +module ActiveModel + class Serializer + class Adapter + class JsonApiAdapter + class BelongsToTest < Minitest::Test + def setup + @post = Post.new(id: 42, title: 'New Post', body: 'Body') + @comment = Comment.new(id: 1, body: 'ZOMG A COMMENT') + @post.comments = [@comment] + @comment.post = @post + + @serializer = CommentSerializer.new(@comment) + @adapter = ActiveModel::Serializer::Adapter::JsonApiAdapter.new(@serializer) + end + + def test_includes_post_id + assert_equal(42, @adapter.serializable_hash[:links][:post]) + end + + def test_includes_linked_post + assert_equal([{id: 42, title: 'New Post', body: 'Body'}], @adapter.serializable_hash[:linked][:posts]) + end + end + end + end + end +end diff --git a/test/adapter/json_api/has_many.rb b/test/adapter/json_api/has_many.rb new file mode 100644 index 00000000..d9377a82 --- /dev/null +++ b/test/adapter/json_api/has_many.rb @@ -0,0 +1,34 @@ +require 'test_helper' + +module ActiveModel + class Serializer + class Adapter + class JsonApiAdapter + class HasManyTest < Minitest::Test + def setup + @post = Post.new(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 + + @serializer = PostSerializer.new(@post) + @adapter = ActiveModel::Serializer::Adapter::JsonApiAdapter.new(@serializer) + end + + def test_includes_comment_ids + assert_equal([1, 2], @adapter.serializable_hash[:links][:comments]) + end + + def test_includes_linked_comments + assert_equal([ + {id: 1, body: 'ZOMG A COMMENT'}, + {id: 2, body: 'ZOMG ANOTHER COMMENT'} + ], @adapter.serializable_hash[:linked][:comments]) + end + end + end + end + end +end diff --git a/test/adapter/json_api_adapter_test.rb b/test/adapter/json_api_adapter_test.rb deleted file mode 100644 index dc09e397..00000000 --- a/test/adapter/json_api_adapter_test.rb +++ /dev/null @@ -1,26 +0,0 @@ -require 'test_helper' - -module ActiveModel - class Serializer - class Adapter - class JsonApiTest < Minitest::Test - def setup - @post = Post.new(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_serializer = PostSerializer.new(@post) - @adapter = ActiveModel::Serializer::Adapter::JsonApiAdapter.new(@post_serializer) - end - - def test_includes_comment_ids - assert_equal([1, 2], @adapter.serializable_hash[:comments]) - end - end - end - end -end -