diff --git a/CHANGELOG.md b/CHANGELOG.md index f237bb24..86086f1e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,8 @@ Breaking changes: Features: +- [#1515](https://github.com/rails-api/active_model_serializers/pull/1515) Adds support for symbols to the + `ActiveModel::Serializer.type` method. (@groyoh) - [#1504](https://github.com/rails-api/active_model_serializers/pull/1504) Adds the changes missing from #1454 and add more tests for resource identifier and relationship objects. Fix association block with link returning `data: nil`.(@groyoh) diff --git a/docs/general/serializers.md b/docs/general/serializers.md index 4014cfe2..65ccaa1a 100644 --- a/docs/general/serializers.md +++ b/docs/general/serializers.md @@ -107,12 +107,30 @@ end #### ::type -e.g. +The `::type` method defines the JSONAPI [type](http://jsonapi.org/format/#document-resource-object-identification) that will be rendered for this serializer. +It either takes a `String` or `Symbol` as parameter. +Note: This method is useful only when using the `:json_api` adapter. + +Examples: ```ruby class UserProfileSerializer < ActiveModel::Serializer type 'profile' end +class AuthorProfileSerializer < ActiveModel::Serializer + type :profile +end +``` + +With the `:json_api` adapter, the previous serializers would be rendered as: + +``` json +{ + "data": { + "id": "1", + "type": "profile" + } +} ``` #### ::link diff --git a/lib/active_model/serializer/type.rb b/lib/active_model/serializer/type.rb index 563cb694..c37c9af8 100644 --- a/lib/active_model/serializer/type.rb +++ b/lib/active_model/serializer/type.rb @@ -17,7 +17,7 @@ module ActiveModel # class AdminAuthorSerializer < ActiveModel::Serializer # type 'authors' def type(type) - self._type = type + self._type = type && type.to_s end end end diff --git a/test/adapter/json_api/resource_type_config_test.rb b/test/adapter/json_api/resource_type_config_test.rb deleted file mode 100644 index d4301c75..00000000 --- a/test/adapter/json_api/resource_type_config_test.rb +++ /dev/null @@ -1,71 +0,0 @@ -require 'test_helper' - -module ActiveModel - class Serializer - module Adapter - class JsonApi - class ResourceTypeConfigTest < ActiveSupport::TestCase - class ProfileTypeSerializer < ActiveModel::Serializer - attributes :name - type 'profile' - end - - def setup - @author = Author.new(id: 1, name: 'Steve K.') - @author.bio = nil - @author.roles = [] - @blog = Blog.new(id: 23, name: 'AMS Blog') - @post = Post.new(id: 42, title: 'New Post', body: 'Body') - @anonymous_post = Post.new(id: 43, title: 'Hello!!', body: 'Hello, world!!') - @comment = Comment.new(id: 1, body: 'ZOMG A COMMENT') - @post.comments = [@comment] - @post.blog = @blog - @anonymous_post.comments = [] - @anonymous_post.blog = nil - @comment.post = @post - @comment.author = nil - @post.author = @author - @anonymous_post.author = nil - @blog = Blog.new(id: 1, name: 'My Blog!!') - @blog.writer = @author - @blog.articles = [@post, @anonymous_post] - @author.posts = [] - end - - def with_jsonapi_resource_type type - old_type = ActiveModelSerializers.config.jsonapi_resource_type - ActiveModelSerializers.config.jsonapi_resource_type = type - yield - ensure - ActiveModelSerializers.config.jsonapi_resource_type = old_type - end - - def test_config_plural - with_jsonapi_resource_type :plural do - hash = serializable(@comment, adapter: :json_api).serializable_hash - assert_equal('comments', hash[:data][:type]) - end - end - - def test_config_singular - with_jsonapi_resource_type :singular do - hash = serializable(@comment, adapter: :json_api).serializable_hash - assert_equal('comment', hash[:data][:type]) - end - end - - def test_explicit_type_value - hash = serializable(@author, serializer: ProfileTypeSerializer, adapter: :json_api).serializable_hash - assert_equal('profile', hash.fetch(:data).fetch(:type)) - end - - private - - def serializable(resource, options = {}) - ActiveModel::SerializableResource.new(resource, options) - end - end - end - end - end -end diff --git a/test/adapter/json_api/type_test.rb b/test/adapter/json_api/type_test.rb new file mode 100644 index 00000000..d034957e --- /dev/null +++ b/test/adapter/json_api/type_test.rb @@ -0,0 +1,61 @@ +require 'test_helper' + +module ActiveModel + class Serializer + module Adapter + class JsonApi + class TypeTest < ActiveSupport::TestCase + class StringTypeSerializer < ActiveModel::Serializer + attribute :name + type 'profile' + end + + class SymbolTypeSerializer < ActiveModel::Serializer + attribute :name + type :profile + end + + setup do + @author = Author.new(id: 1, name: 'Steve K.') + end + + def test_config_plural + with_jsonapi_resource_type :plural do + assert_type(@author, 'authors') + end + end + + def test_config_singular + with_jsonapi_resource_type :singular do + assert_type(@author, 'author') + end + end + + def test_explicit_string_type_value + assert_type(@author, 'profile', serializer: StringTypeSerializer) + end + + def test_explicit_symbol_type_value + assert_type(@author, 'profile', serializer: SymbolTypeSerializer) + end + + private + + def assert_type(resource, expected_type, opts = {}) + opts = opts.reverse_merge(adapter: :json_api) + hash = serializable(resource, opts).serializable_hash + assert_equal(expected_type, hash.fetch(:data).fetch(:type)) + end + + def with_jsonapi_resource_type inflection + old_inflection = ActiveModelSerializers.config.jsonapi_resource_type + ActiveModelSerializers.config.jsonapi_resource_type = inflection + yield + ensure + ActiveModelSerializers.config.jsonapi_resource_type = old_inflection + end + end + end + end + end +end