Skip to content

Commit 968bbf3

Browse files
committed
Type transform setting and transformer, name fixed in tests
1 parent ac5bbab commit 968bbf3

File tree

5 files changed

+46
-13
lines changed

5 files changed

+46
-13
lines changed

docs/general/configuration_options.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,17 @@ Possible values:
6767

6868
Sets separator string for namespaced models to render `type` attribute. Default value is `--`.
6969

70+
##### jsonapi_type_transform
71+
72+
Provides transform for `type` attribute. Class name `NicePost` gets converted into `nice_post`, `nice-post`, `NicePost` or `nicePost` depending on selected setting.
73+
74+
Possible values:
75+
76+
- `:underscore` (default)
77+
- `:dashed`
78+
- `:camel`
79+
- `:snake`
80+
7081
##### jsonapi_include_toplevel_object
7182

7283
Include a [top level jsonapi member](http://jsonapi.org/format/#document-jsonapi-object)

lib/active_model/serializer/configuration.rb

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@ def config.array_serializer
2121

2222
config.adapter = :attributes
2323
config.jsonapi_resource_type = :plural
24-
config.jsonapi_namespace_separator = '--'
24+
config.jsonapi_namespace_separator = '--'.freeze
25+
config.jsonapi_type_transform = :underscore
2526
config.jsonapi_version = '1.0'
2627
config.jsonapi_toplevel_meta = {}
2728
# Make JSON API top-level jsonapi member opt-in

lib/active_model_serializers/adapter/json_api/resource_identifier.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ def as_json
2121
def type_for(serializer)
2222
return serializer._type if serializer._type
2323
type = serializer.object.class.to_s.split('::')
24-
type.map! { |t| t.underscore.downcase }
24+
type.map! { |t| KeyTransform.transform(t, ActiveModelSerializers.config.jsonapi_type_transform) }
2525
type = type.join ActiveModelSerializers.config.jsonapi_namespace_separator
2626
if ActiveModelSerializers.config.jsonapi_resource_type == :plural
2727
type = type.pluralize

lib/active_model_serializers/key_transform.rb

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,5 +36,26 @@ def dashed(hash)
3636
def unaltered(hash)
3737
hash
3838
end
39+
40+
# Transforms string to selected case
41+
# Accepts string in any case: 'camel', 'undescore', 'dashed'.
42+
#
43+
# @example:
44+
# transform('SomeClass', :underscore) => 'some_class'
45+
# transform('some_class', :snake) => 'someClass'
46+
# etc...
47+
def transform(string, type)
48+
string = string.underscore
49+
case type.to_sym
50+
when :dashed
51+
string.dasherize
52+
when :camel
53+
string.camelize
54+
when :snake
55+
string.camelize(:lower)
56+
else
57+
string
58+
end
59+
end
3960
end
4061
end

test/adapter/json_api/resource_identifier_test.rb

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -22,54 +22,54 @@ class FragmentedSerializer < ActiveModel::Serializer; end
2222
end
2323

2424
def test_defined_type
25-
test(WithDefinedTypeSerializer.new(@model), type: 'with_defined_type')
25+
assert_identifier(WithDefinedTypeSerializer.new(@model), type: 'with_defined_type')
2626
end
2727

2828
def test_singular_type
29-
test(AuthorSerializer.new(@model), type: 'author', inflection: :singular)
29+
assert_with_confing(AuthorSerializer.new(@model), type: 'author', inflection: :singular)
3030
end
3131

3232
def test_plural_type
33-
test(AuthorSerializer.new(@model), type: 'authors', inflection: :plural)
33+
assert_with_confing(AuthorSerializer.new(@model), type: 'authors', inflection: :plural)
3434
end
3535

3636
def test_type_with_namespace
3737
spam = Spam::UnrelatedLink.new
38-
test(Spam::UnrelatedLinkSerializer.new(spam), type: 'spam--unrelated_links')
38+
assert_identifier(Spam::UnrelatedLinkSerializer.new(spam), type: 'spam--unrelated_links')
3939
end
4040

4141
def test_type_with_custom_namespace
4242
spam = Spam::UnrelatedLink.new
43-
test(Spam::UnrelatedLinkSerializer.new(spam), type: 'spam/unrelated_links', namespace_separator: '/')
43+
assert_with_confing(Spam::UnrelatedLinkSerializer.new(spam), type: 'spam/unrelated_links', namespace_separator: '/')
4444
end
4545

4646
def test_id_defined_on_object
47-
test(AuthorSerializer.new(@model), id: @model.id.to_s)
47+
assert_identifier(AuthorSerializer.new(@model), id: @model.id.to_s)
4848
end
4949

5050
def test_id_defined_on_serializer
51-
test(WithDefinedIdSerializer.new(@model), id: 'special_id')
51+
assert_identifier(WithDefinedIdSerializer.new(@model), id: 'special_id')
5252
end
5353

5454
def test_id_defined_on_fragmented
5555
FragmentedSerializer.fragmented(WithDefinedIdSerializer.new(@author))
56-
test(FragmentedSerializer.new(@model), id: 'special_id')
56+
assert_identifier(FragmentedSerializer.new(@model), id: 'special_id')
5757
end
5858

5959
private
6060

61-
def test(serializer, opts = {})
61+
def assert_with_confing(serializer, opts = {})
6262
inflection = ActiveModelSerializers.config.jsonapi_resource_type
6363
namespace_separator = ActiveModelSerializers.config.jsonapi_namespace_separator
6464
ActiveModelSerializers.config.jsonapi_resource_type = opts.fetch(:inflection, inflection)
6565
ActiveModelSerializers.config.jsonapi_namespace_separator = opts.fetch(:namespace_separator, namespace_separator)
66-
test_serializer(serializer, opts)
66+
assert_identifier(serializer, opts)
6767
ensure
6868
ActiveModelSerializers.config.jsonapi_resource_type = inflection
6969
ActiveModelSerializers.config.jsonapi_namespace_separator = namespace_separator
7070
end
7171

72-
def test_serializer(serializer, opts = {})
72+
def assert_identifier(serializer, opts = {})
7373
identifier = ResourceIdentifier.new(serializer)
7474
expected = {
7575
id: opts.fetch(:id, identifier.as_json[:id]),

0 commit comments

Comments
 (0)