diff --git a/lib/active_model/serializer.rb b/lib/active_model/serializer.rb index 106c5e71..1bfdf825 100644 --- a/lib/active_model/serializer.rb +++ b/lib/active_model/serializer.rb @@ -108,12 +108,7 @@ module ActiveModel self.class._associations.dup.each_with_object({}) do |(name, value), hash| association = object.send(name) serializer_class = ActiveModel::Serializer.serializer_for(association) - if serializer_class - serializer = serializer_class.new(association) - hash[name] = serializer - else - hash[name] = association - end + hash[name] = serializer_class.new(association) end end end diff --git a/lib/active_model/serializer/adapter/json_api_adapter.rb b/lib/active_model/serializer/adapter/json_api_adapter.rb index 5f5df719..14094417 100644 --- a/lib/active_model/serializer/adapter/json_api_adapter.rb +++ b/lib/active_model/serializer/adapter/json_api_adapter.rb @@ -3,20 +3,21 @@ module ActiveModel class Adapter class JsonApiAdapter < Adapter def serializable_hash(options = {}) - hash = serializer.attributes.each_with_object({}) do |(attr, value), h| - h[attr] = value - end + hash = serializer.attributes - serializer.associations(only: [:id]).each_with_object({}) do |(attr, value), h| - case value - when ActiveModel::Serializer::ArraySerializer - # process has_many association - when ActiveModel::Serializer - # process belongs_to association - else - # what? - end + associations = serializer.associations(only: [:id]).each_with_object({}) do |(attr, value), h| + h[attr] = case value + when ActiveModel::Serializer::ArraySerializer + value.attributes(options).map do |item| + item.id + end.to_a + when ActiveModel::Serializer + # process belongs_to association + else + # what? + end end + hash.merge(associations) end end end diff --git a/lib/active_model/serializer/array_serializer.rb b/lib/active_model/serializer/array_serializer.rb index 13ab08c7..c2751f4b 100644 --- a/lib/active_model/serializer/array_serializer.rb +++ b/lib/active_model/serializer/array_serializer.rb @@ -4,6 +4,13 @@ module ActiveModel def initialize(object) @object = object end + + def attributes(options = {}) + object.map do |item| + serializer_class = ActiveModel::Serializer.serializer_for(item) + serializer_class.new(item) + end + end end end end diff --git a/test/adapter/json_api_adapter_test.rb b/test/adapter/json_api_adapter_test.rb index c49a90c1..dc09e397 100644 --- a/test/adapter/json_api_adapter_test.rb +++ b/test/adapter/json_api_adapter_test.rb @@ -5,24 +5,19 @@ module ActiveModel class Adapter class JsonApiTest < Minitest::Test def setup - @post = ::Model.new(title: 'New Post', body: 'Body') - @first_comment = ::Model.new(id: 1, body: 'ZOMG A COMMENT') - @second_comment = ::Model.new(id: 2, body: 'ZOMG ANOTHER COMMENT') + @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_class = def_serializer do - attributes :title, :body - has_many :comments - end - - @post_serializer = @post_serializer_class.new(@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]) + assert_equal([1, 2], @adapter.serializable_hash[:comments]) end end end diff --git a/test/fixtures/poro.rb b/test/fixtures/poro.rb index 8876a73d..8359fcb7 100644 --- a/test/fixtures/poro.rb +++ b/test/fixtures/poro.rb @@ -5,12 +5,16 @@ class Model def read_attribute_for_serialization(name) if name == :id || name == 'id' - object_id + id else @attributes[name] end end + def id + @attributes[:id] || @attributes['id'] || object_id + end + def method_missing(meth, *args) if meth.to_s =~ /^(.*)=$/ @attributes[$1.to_sym] = args[0] @@ -28,3 +32,18 @@ end class ProfileSerializer < ActiveModel::Serializer attributes :name, :description end + +Post = Class.new(Model) +Comment = Class.new(Model) + +PostSerializer = Class.new(ActiveModel::Serializer) do + attributes :title, :body, :id + + has_many :comments +end + +CommentSerializer = Class.new(ActiveModel::Serializer) do + attributes :id, :body + + belongs_to :post +end diff --git a/test/serializers/associations_test.rb b/test/serializers/associations_test.rb index 45fbd8d1..56603b2c 100644 --- a/test/serializers/associations_test.rb +++ b/test/serializers/associations_test.rb @@ -3,10 +3,6 @@ require 'test_helper' module ActiveModel class Serializer class AssocationsTest < Minitest::Test - def def_serializer(&block) - Class.new(ActiveModel::Serializer, &block) - end - class Model def initialize(hash={}) @attributes = hash @@ -26,19 +22,7 @@ module ActiveModel end end end - Post = Class.new(Model) - Comment = Class.new(Model) - PostSerializer = Class.new(ActiveModel::Serializer) do - attributes :title, :body - has_many :comments - end - - CommentSerializer = Class.new(ActiveModel::Serializer) do - attributes :id, :body - - belongs_to :post - end def setup @post = Post.new({ title: 'New Post', body: 'Body' })