diff --git a/CHANGELOG.md b/CHANGELOG.md index 00ea5fa81..80cd0c683 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,7 @@ Breaking changes: Features: +- [#1406](https://github.com/rails-api/active_model_serializers/pull/1406) Allow for custom dynamic values in JSON API links (@beauby) - [#1270](https://github.com/rails-api/active_model_serializers/pull/1270) Adds `assert_response_schema` test helper (@maurogeorge) - [#1099](https://github.com/rails-api/active_model_serializers/pull/1099) Adds `assert_serializer` test helper (@maurogeorge) - [#1403](https://github.com/rails-api/active_model_serializers/pull/1403) Add support for if/unless on attributes/associations (@beauby) diff --git a/lib/active_model/serializer/adapter/json_api.rb b/lib/active_model/serializer/adapter/json_api.rb index bf1e38ffb..04c2e4a77 100644 --- a/lib/active_model/serializer/adapter/json_api.rb +++ b/lib/active_model/serializer/adapter/json_api.rb @@ -209,16 +209,8 @@ def add_included_resources_for(serializer, include_tree, primary_data, included) end def links_for(serializer) - serializer._links.each_with_object({}) do |(name, value), hash| - hash[name] = - if value.respond_to?(:call) - link = Link.new(serializer) - link.instance_eval(&value) - - link.to_hash - else - value - end + serializer.links.each_with_object({}) do |(name, value), hash| + hash[name] = Link.new(serializer, value).as_json end end diff --git a/lib/active_model/serializer/adapter/json_api/link.rb b/lib/active_model/serializer/adapter/json_api/link.rb index 45ce89609..bed230c33 100644 --- a/lib/active_model/serializer/adapter/json_api/link.rb +++ b/lib/active_model/serializer/adapter/json_api/link.rb @@ -3,29 +3,39 @@ class Serializer module Adapter class JsonApi class Link - def initialize(serializer) + def initialize(serializer, value) @object = serializer.object @scope = serializer.scope + + # Use the return value of the block unless it is nil. + if value.respond_to?(:call) + @value = instance_eval(&value) + else + @value = value + end end def href(value) - self._href = value + @href = value + nil end def meta(value) - self._meta = value + @meta = value + nil end - def to_hash - hash = { href: _href } - hash.merge!(meta: _meta) if _meta + def as_json + return @value if @value + + hash = { href: @href } + hash.merge!(meta: @meta) if @meta hash end protected - attr_accessor :_href, :_meta attr_reader :object, :scope end end diff --git a/test/adapter/json_api/links_test.rb b/test/adapter/json_api/links_test.rb index 1c5a66036..dbda88ea0 100644 --- a/test/adapter/json_api/links_test.rb +++ b/test/adapter/json_api/links_test.rb @@ -13,6 +13,10 @@ class LinkAuthorSerializer < ActiveModel::Serializer end link :other, '//example.com/resource' + + link :yet_another do + "//example.com/resource/#{object.id}" + end end def setup @@ -52,7 +56,8 @@ def test_resource_links stuff: 'value' } }, - other: '//example.com/resource' + other: '//example.com/resource', + yet_another: '//example.com/resource/1337' } assert_equal(expected, hash[:data][:links]) end