diff --git a/.gitignore b/.gitignore index 0374e060e..a2e13e610 100644 --- a/.gitignore +++ b/.gitignore @@ -19,3 +19,4 @@ test/version_tmp tmp *.swp .ruby-version +tags diff --git a/CHANGELOG.md b/CHANGELOG.md index 28f1e822e..02960fe67 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,4 +9,5 @@ * adds cache support to attributes and associations [@joaomdmoura] * uses model name to determine the type [@lsylvester] * remove root key option and split JSON adapter [@joaomdmoura] - * adds FlattenJSON as default adapter [@joaomdmoura] \ No newline at end of file + * adds FlattenJSON as default adapter [@joaomdmoura] + * adds support for `links` at top level of JsonApi adapter [@leandrocp] diff --git a/lib/active_model/serializer/adapter.rb b/lib/active_model/serializer/adapter.rb index 623bddb7e..7c0614342 100644 --- a/lib/active_model/serializer/adapter.rb +++ b/lib/active_model/serializer/adapter.rb @@ -22,10 +22,7 @@ def serializable_hash(options = nil) def as_json(options = nil) hash = serializable_hash(options) - unless self.class == FlattenJson - include_meta(hash) - include_links(hash) - end + include_meta(hash) unless self.class == FlattenJson hash end @@ -89,10 +86,6 @@ def meta_key serializer.meta_key || "meta" end - def links - serializer.links if serializer.respond_to?(:links) - end - def root serializer.json_key.to_sym if serializer.json_key end @@ -101,11 +94,6 @@ def include_meta(json) json[meta_key] = meta if meta json end - - def include_links(json) - json["links"] = links if links - json - end end end end diff --git a/lib/active_model/serializer/adapter/json_api.rb b/lib/active_model/serializer/adapter/json_api.rb index 551ed54b1..db42182c8 100644 --- a/lib/active_model/serializer/adapter/json_api.rb +++ b/lib/active_model/serializer/adapter/json_api.rb @@ -31,6 +31,7 @@ def serializable_hash(options = nil) @hash[:data] = attributes_for_serializer(serializer, options) add_resource_relationships(@hash[:data], serializer) end + @hash[:links] = attributes_for_top_level_links(serializer) if serializer.links @hash end @@ -157,6 +158,10 @@ def add_resource_relationships(attrs, serializer, options = {}) end end end + + def attributes_for_top_level_links(serializer) + serializer.links + end end end end diff --git a/test/serializers/links_test.rb b/test/serializers/links_test.rb index 54aa1b918..c9c77e6c0 100644 --- a/test/serializers/links_test.rb +++ b/test/serializers/links_test.rb @@ -12,84 +12,51 @@ def setup end def test_links_is_present_with_root - serializer = AlternateBlogSerializer.new(@blog, :links => {"self" => "/blogs/1"}) - adapter = ActiveModel::Serializer::Adapter::Json.new(serializer) + serializer = AlternateBlogSerializer.new(@blog, :links => {:self => "/blogs/1"}) + adapter = ActiveModel::Serializer::Adapter::JsonApi.new(serializer) expected = { - blog: { - id: 1, - title: "AMS Hints" + data: { + id: "1", + type: "blogs", + attributes: { + title: "AMS Hints" + } }, - "links" => { - "self" => "/blogs/1" + links: { + self: "/blogs/1" } } assert_equal expected, adapter.as_json end - def test_links_is_not_included_when_root_is_missing - # load_adapter uses FlattenJson Adapter - adapter = load_adapter(links: {"self" => "/blogs/1"}) + def test_links_is_not_present_when_not_declared + serializer = AlternateBlogSerializer.new(@blog) + adapter = ActiveModel::Serializer::Adapter::JsonApi.new(serializer) expected = { - id: 1, - title: "AMS Hints" + data: { + id: "1", + type: "blogs", + attributes: { + title: "AMS Hints" + } + } } assert_equal expected, adapter.as_json end - def test_links_is_not_present_on_arrays_without_root - serializer = ArraySerializer.new([@blog], links: {"self" => "/blogs/1"}) - # FlattenJSON doesn't have support to root + def test_links_is_not_present_on_flattenjson_adapter + serializer = AlternateBlogSerializer.new(@blog, :links => {:self => "/blogs/1"}) adapter = ActiveModel::Serializer::Adapter::FlattenJson.new(serializer) - expected = [{ - id: 1, - name: "AMS Hints", - writer: { - id: 2, - name: "Steve" - }, - articles: [{ - id: 3, - title: "AMS", - body: nil - }] - }] + expected = {:id=>1, :title=>"AMS Hints"} assert_equal expected, adapter.as_json end - def test_links_is_present_on_arrays_with_root - serializer = ArraySerializer.new([@blog], links: {"self" => "/blogs/1"}) - # JSON adapter adds root by default + def test_links_is_not_present_on_json_adapter + serializer = AlternateBlogSerializer.new(@blog, :links => {:self => "/blogs/1"}) adapter = ActiveModel::Serializer::Adapter::Json.new(serializer) - expected = { - blogs: [{ - id: 1, - name: "AMS Hints", - writer: { - id: 2, - name: "Steve" - }, - articles: [{ - id: 3, - title: "AMS", - body: nil - }] - }], - "links" => { - "self" => "/blogs/1" - } - } + expected = {:blog=>{:id=>1, :title=>"AMS Hints"}} assert_equal expected, adapter.as_json end - - private - - def load_adapter(options) - adapter_opts, serializer_opts = - options.partition { |k, _| ActionController::Serialization::ADAPTER_OPTION_KEYS.include? k }.map { |h| Hash[h] } - - serializer = AlternateBlogSerializer.new(@blog, serializer_opts) - ActiveModel::Serializer::Adapter::FlattenJson.new(serializer, adapter_opts) - end end end end