active_model_serializers 0.10.0 → 0.10.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/.rubocop.yml +10 -5
- data/.travis.yml +41 -21
- data/CHANGELOG.md +200 -2
- data/CODE_OF_CONDUCT.md +74 -0
- data/Gemfile +25 -4
- data/README.md +166 -28
- data/Rakefile +5 -32
- data/active_model_serializers.gemspec +23 -25
- data/appveyor.yml +10 -6
- data/bin/rubocop +38 -0
- data/docs/README.md +2 -1
- data/docs/general/adapters.md +35 -11
- data/docs/general/caching.md +7 -1
- data/docs/general/configuration_options.md +86 -1
- data/docs/general/deserialization.md +1 -1
- data/docs/general/fields.md +31 -0
- data/docs/general/getting_started.md +1 -1
- data/docs/general/logging.md +7 -0
- data/docs/general/rendering.md +63 -25
- data/docs/general/serializers.md +137 -14
- data/docs/howto/add_pagination_links.md +16 -17
- data/docs/howto/add_relationship_links.md +140 -0
- data/docs/howto/add_root_key.md +11 -0
- data/docs/howto/grape_integration.md +42 -0
- data/docs/howto/outside_controller_use.md +12 -4
- data/docs/howto/passing_arbitrary_options.md +2 -2
- data/docs/howto/serialize_poro.md +46 -5
- data/docs/howto/test.md +2 -0
- data/docs/howto/upgrade_from_0_8_to_0_10.md +265 -0
- data/docs/integrations/ember-and-json-api.md +67 -32
- data/docs/jsonapi/schema.md +1 -1
- data/lib/action_controller/serialization.rb +15 -3
- data/lib/active_model/serializable_resource.rb +2 -0
- data/lib/active_model/serializer/adapter/attributes.rb +2 -0
- data/lib/active_model/serializer/adapter/base.rb +4 -0
- data/lib/active_model/serializer/adapter/json.rb +2 -0
- data/lib/active_model/serializer/adapter/json_api.rb +2 -0
- data/lib/active_model/serializer/adapter/null.rb +2 -0
- data/lib/active_model/serializer/adapter.rb +2 -0
- data/lib/active_model/serializer/array_serializer.rb +10 -5
- data/lib/active_model/serializer/association.rb +64 -10
- data/lib/active_model/serializer/attribute.rb +2 -0
- data/lib/active_model/serializer/belongs_to_reflection.rb +6 -3
- data/lib/active_model/serializer/collection_serializer.rb +39 -13
- data/lib/active_model/serializer/{caching.rb → concerns/caching.rb} +87 -116
- data/lib/active_model/serializer/error_serializer.rb +13 -7
- data/lib/active_model/serializer/errors_serializer.rb +27 -20
- data/lib/active_model/serializer/field.rb +2 -0
- data/lib/active_model/serializer/fieldset.rb +2 -0
- data/lib/active_model/serializer/has_many_reflection.rb +5 -3
- data/lib/active_model/serializer/has_one_reflection.rb +3 -4
- data/lib/active_model/serializer/lazy_association.rb +99 -0
- data/lib/active_model/serializer/link.rb +23 -0
- data/lib/active_model/serializer/lint.rb +136 -130
- data/lib/active_model/serializer/null.rb +2 -0
- data/lib/active_model/serializer/reflection.rb +132 -67
- data/lib/active_model/serializer/version.rb +3 -1
- data/lib/active_model/serializer.rb +308 -82
- data/lib/active_model_serializers/adapter/attributes.rb +5 -66
- data/lib/active_model_serializers/adapter/base.rb +41 -39
- data/lib/active_model_serializers/adapter/json.rb +2 -0
- data/lib/active_model_serializers/adapter/json_api/deserialization.rb +4 -2
- data/lib/active_model_serializers/adapter/json_api/error.rb +2 -0
- data/lib/active_model_serializers/adapter/json_api/jsonapi.rb +2 -0
- data/lib/active_model_serializers/adapter/json_api/link.rb +3 -1
- data/lib/active_model_serializers/adapter/json_api/meta.rb +2 -0
- data/lib/active_model_serializers/adapter/json_api/pagination_links.rb +49 -21
- data/lib/active_model_serializers/adapter/json_api/relationship.rb +77 -23
- data/lib/active_model_serializers/adapter/json_api/resource_identifier.rb +41 -10
- data/lib/active_model_serializers/adapter/json_api.rb +84 -65
- data/lib/active_model_serializers/adapter/null.rb +2 -0
- data/lib/active_model_serializers/adapter.rb +9 -1
- data/lib/active_model_serializers/callbacks.rb +2 -0
- data/lib/active_model_serializers/deprecate.rb +3 -2
- data/lib/active_model_serializers/deserialization.rb +4 -0
- data/lib/active_model_serializers/json_pointer.rb +2 -0
- data/lib/active_model_serializers/logging.rb +2 -0
- data/lib/active_model_serializers/lookup_chain.rb +82 -0
- data/lib/active_model_serializers/model.rb +111 -28
- data/lib/active_model_serializers/railtie.rb +7 -1
- data/lib/active_model_serializers/register_jsonapi_renderer.rb +46 -31
- data/lib/active_model_serializers/serializable_resource.rb +10 -7
- data/lib/active_model_serializers/serialization_context.rb +12 -3
- data/lib/active_model_serializers/test/schema.rb +4 -2
- data/lib/active_model_serializers/test/serializer.rb +2 -0
- data/lib/active_model_serializers/test.rb +2 -0
- data/lib/active_model_serializers.rb +35 -10
- data/lib/generators/rails/resource_override.rb +3 -1
- data/lib/generators/rails/serializer_generator.rb +6 -4
- data/lib/grape/active_model_serializers.rb +9 -5
- data/lib/grape/formatters/active_model_serializers.rb +21 -2
- data/lib/grape/helpers/active_model_serializers.rb +3 -0
- data/lib/tasks/rubocop.rake +55 -0
- data/test/action_controller/adapter_selector_test.rb +16 -5
- data/test/action_controller/explicit_serializer_test.rb +7 -4
- data/test/action_controller/json/include_test.rb +108 -27
- data/test/action_controller/json_api/deserialization_test.rb +3 -1
- data/test/action_controller/json_api/errors_test.rb +10 -9
- data/test/action_controller/json_api/fields_test.rb +68 -0
- data/test/action_controller/json_api/linked_test.rb +31 -24
- data/test/action_controller/json_api/pagination_test.rb +33 -23
- data/test/action_controller/json_api/transform_test.rb +13 -3
- data/test/action_controller/lookup_proc_test.rb +51 -0
- data/test/action_controller/namespace_lookup_test.rb +234 -0
- data/test/action_controller/serialization_scope_name_test.rb +14 -6
- data/test/action_controller/serialization_test.rb +23 -12
- data/test/active_model_serializers/adapter_for_test.rb +2 -0
- data/test/active_model_serializers/json_pointer_test.rb +17 -13
- data/test/active_model_serializers/logging_test.rb +2 -0
- data/test/active_model_serializers/model_test.rb +139 -4
- data/test/active_model_serializers/railtie_test_isolated.rb +14 -7
- data/test/active_model_serializers/register_jsonapi_renderer_test_isolated.rb +163 -0
- data/test/active_model_serializers/serialization_context_test_isolated.rb +25 -10
- data/test/active_model_serializers/test/schema_test.rb +5 -2
- data/test/active_model_serializers/test/serializer_test.rb +2 -0
- data/test/active_record_test.rb +2 -0
- data/test/adapter/attributes_test.rb +42 -0
- data/test/adapter/deprecation_test.rb +2 -0
- data/test/adapter/json/belongs_to_test.rb +2 -0
- data/test/adapter/json/collection_test.rb +16 -0
- data/test/adapter/json/has_many_test.rb +12 -2
- data/test/adapter/json/transform_test.rb +17 -15
- data/test/adapter/json_api/belongs_to_test.rb +2 -0
- data/test/adapter/json_api/collection_test.rb +6 -3
- data/test/adapter/json_api/errors_test.rb +19 -19
- data/test/adapter/json_api/fields_test.rb +14 -3
- data/test/adapter/json_api/has_many_explicit_serializer_test.rb +2 -0
- data/test/adapter/json_api/has_many_test.rb +51 -20
- data/test/adapter/json_api/has_one_test.rb +2 -0
- data/test/adapter/json_api/include_data_if_sideloaded_test.rb +215 -0
- data/test/adapter/json_api/json_api_test.rb +7 -7
- data/test/adapter/json_api/linked_test.rb +35 -12
- data/test/adapter/json_api/links_test.rb +22 -3
- data/test/adapter/json_api/pagination_links_test.rb +55 -13
- data/test/adapter/json_api/parse_test.rb +3 -1
- data/test/adapter/json_api/relationship_test.rb +311 -73
- data/test/adapter/json_api/resource_meta_test.rb +5 -3
- data/test/adapter/json_api/toplevel_jsonapi_test.rb +2 -0
- data/test/adapter/json_api/transform_test.rb +265 -253
- data/test/adapter/json_api/type_test.rb +170 -36
- data/test/adapter/json_test.rb +10 -7
- data/test/adapter/null_test.rb +3 -2
- data/test/adapter/polymorphic_test.rb +54 -5
- data/test/adapter_test.rb +3 -1
- data/test/array_serializer_test.rb +2 -0
- data/test/benchmark/app.rb +3 -1
- data/test/benchmark/benchmarking_support.rb +3 -1
- data/test/benchmark/bm_active_record.rb +83 -0
- data/test/benchmark/bm_adapter.rb +40 -0
- data/test/benchmark/bm_caching.rb +18 -16
- data/test/benchmark/bm_lookup_chain.rb +85 -0
- data/test/benchmark/bm_transform.rb +23 -10
- data/test/benchmark/controllers.rb +18 -17
- data/test/benchmark/fixtures.rb +74 -72
- data/test/cache_test.rb +301 -69
- data/test/collection_serializer_test.rb +33 -14
- data/test/fixtures/active_record.rb +47 -10
- data/test/fixtures/poro.rb +128 -183
- data/test/generators/scaffold_controller_generator_test.rb +2 -0
- data/test/generators/serializer_generator_test.rb +25 -5
- data/test/grape_test.rb +172 -56
- data/test/lint_test.rb +3 -1
- data/test/logger_test.rb +15 -11
- data/test/poro_test.rb +2 -0
- data/test/serializable_resource_test.rb +20 -22
- data/test/serializers/association_macros_test.rb +5 -2
- data/test/serializers/associations_test.rb +274 -49
- data/test/serializers/attribute_test.rb +7 -3
- data/test/serializers/attributes_test.rb +3 -1
- data/test/serializers/caching_configuration_test_isolated.rb +8 -6
- data/test/serializers/configuration_test.rb +2 -0
- data/test/serializers/fieldset_test.rb +3 -1
- data/test/serializers/meta_test.rb +14 -6
- data/test/serializers/options_test.rb +19 -6
- data/test/serializers/read_attribute_for_serialization_test.rb +5 -3
- data/test/serializers/reflection_test.rb +481 -0
- data/test/serializers/root_test.rb +3 -1
- data/test/serializers/serialization_test.rb +4 -2
- data/test/serializers/serializer_for_test.rb +14 -10
- data/test/serializers/serializer_for_with_namespace_test.rb +90 -0
- data/test/support/isolated_unit.rb +11 -4
- data/test/support/rails5_shims.rb +10 -2
- data/test/support/rails_app.rb +4 -9
- data/test/support/serialization_testing.rb +33 -5
- data/test/test_helper.rb +15 -0
- metadata +126 -46
- data/.rubocop_todo.yml +0 -167
- data/docs/ARCHITECTURE.md +0 -126
- data/lib/active_model/serializer/associations.rb +0 -100
- data/lib/active_model/serializer/attributes.rb +0 -82
- data/lib/active_model/serializer/collection_reflection.rb +0 -7
- data/lib/active_model/serializer/configuration.rb +0 -35
- data/lib/active_model/serializer/include_tree.rb +0 -111
- data/lib/active_model/serializer/links.rb +0 -35
- data/lib/active_model/serializer/meta.rb +0 -29
- data/lib/active_model/serializer/singular_reflection.rb +0 -7
- data/lib/active_model/serializer/type.rb +0 -25
- data/lib/active_model_serializers/key_transform.rb +0 -70
- data/test/active_model_serializers/key_transform_test.rb +0 -263
- data/test/adapter/json_api/has_many_embed_ids_test.rb +0 -43
- data/test/adapter/json_api/relationships_test.rb +0 -199
- data/test/adapter/json_api/resource_identifier_test.rb +0 -85
- data/test/include_tree/from_include_args_test.rb +0 -26
- data/test/include_tree/from_string_test.rb +0 -94
- data/test/include_tree/include_args_to_hash_test.rb +0 -64
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require 'test_helper'
|
|
2
4
|
require 'will_paginate/array'
|
|
3
5
|
require 'kaminari'
|
|
@@ -13,11 +15,11 @@ module ActiveModelSerializers
|
|
|
13
15
|
def setup
|
|
14
16
|
ActionController::Base.cache_store.clear
|
|
15
17
|
@array = [
|
|
16
|
-
Profile.new(
|
|
17
|
-
Profile.new(
|
|
18
|
-
Profile.new(
|
|
19
|
-
Profile.new(
|
|
20
|
-
Profile.new(
|
|
18
|
+
Profile.new(id: 1, name: 'Name 1', description: 'Description 1', comments: 'Comments 1'),
|
|
19
|
+
Profile.new(id: 2, name: 'Name 2', description: 'Description 2', comments: 'Comments 2'),
|
|
20
|
+
Profile.new(id: 3, name: 'Name 3', description: 'Description 3', comments: 'Comments 3'),
|
|
21
|
+
Profile.new(id: 4, name: 'Name 4', description: 'Description 4', comments: 'Comments 4'),
|
|
22
|
+
Profile.new(id: 5, name: 'Name 5', description: 'Description 5', comments: 'Comments 5')
|
|
21
23
|
]
|
|
22
24
|
end
|
|
23
25
|
|
|
@@ -43,7 +45,8 @@ module ActiveModelSerializers
|
|
|
43
45
|
end
|
|
44
46
|
|
|
45
47
|
def data
|
|
46
|
-
{
|
|
48
|
+
{
|
|
49
|
+
data: [
|
|
47
50
|
{ id: '1', type: 'profiles', attributes: { name: 'Name 1', description: 'Description 1' } },
|
|
48
51
|
{ id: '2', type: 'profiles', attributes: { name: 'Name 2', description: 'Description 2' } },
|
|
49
52
|
{ id: '3', type: 'profiles', attributes: { name: 'Name 3', description: 'Description 3' } },
|
|
@@ -53,6 +56,16 @@ module ActiveModelSerializers
|
|
|
53
56
|
}
|
|
54
57
|
end
|
|
55
58
|
|
|
59
|
+
def empty_collection_links
|
|
60
|
+
{
|
|
61
|
+
self: "#{URI}?page%5Bnumber%5D=1&page%5Bsize%5D=2",
|
|
62
|
+
first: "#{URI}?page%5Bnumber%5D=1&page%5Bsize%5D=2",
|
|
63
|
+
prev: nil,
|
|
64
|
+
next: nil,
|
|
65
|
+
last: "#{URI}?page%5Bnumber%5D=1&page%5Bsize%5D=2"
|
|
66
|
+
}
|
|
67
|
+
end
|
|
68
|
+
|
|
56
69
|
def links
|
|
57
70
|
{
|
|
58
71
|
links: {
|
|
@@ -70,12 +83,14 @@ module ActiveModelSerializers
|
|
|
70
83
|
links: {
|
|
71
84
|
self: "#{URI}?page%5Bnumber%5D=3&page%5Bsize%5D=2",
|
|
72
85
|
first: "#{URI}?page%5Bnumber%5D=1&page%5Bsize%5D=2",
|
|
73
|
-
prev: "#{URI}?page%5Bnumber%5D=2&page%5Bsize%5D=2"
|
|
86
|
+
prev: "#{URI}?page%5Bnumber%5D=2&page%5Bsize%5D=2",
|
|
87
|
+
next: nil,
|
|
88
|
+
last: "#{URI}?page%5Bnumber%5D=3&page%5Bsize%5D=2"
|
|
74
89
|
}
|
|
75
90
|
}
|
|
76
91
|
end
|
|
77
92
|
|
|
78
|
-
def
|
|
93
|
+
def expected_response_when_unpaginatable
|
|
79
94
|
data
|
|
80
95
|
end
|
|
81
96
|
|
|
@@ -86,6 +101,12 @@ module ActiveModelSerializers
|
|
|
86
101
|
end
|
|
87
102
|
end
|
|
88
103
|
|
|
104
|
+
def expected_response_without_pagination_links
|
|
105
|
+
{}.tap do |hash|
|
|
106
|
+
hash[:data] = data.values.flatten[2..3]
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
|
|
89
110
|
def expected_response_with_pagination_links_and_additional_params
|
|
90
111
|
new_links = links[:links].each_with_object({}) { |(key, value), hash| hash[key] = "#{value}&test=test" }
|
|
91
112
|
{}.tap do |hash|
|
|
@@ -101,10 +122,10 @@ module ActiveModelSerializers
|
|
|
101
122
|
end
|
|
102
123
|
end
|
|
103
124
|
|
|
104
|
-
def
|
|
125
|
+
def expected_response_with_empty_collection_pagination_links
|
|
105
126
|
{}.tap do |hash|
|
|
106
127
|
hash[:data] = []
|
|
107
|
-
hash
|
|
128
|
+
hash.merge! links: empty_collection_links
|
|
108
129
|
end
|
|
109
130
|
end
|
|
110
131
|
|
|
@@ -121,7 +142,7 @@ module ActiveModelSerializers
|
|
|
121
142
|
end
|
|
122
143
|
|
|
123
144
|
def test_pagination_links_with_additional_params
|
|
124
|
-
adapter = load_adapter(using_will_paginate, mock_request(
|
|
145
|
+
adapter = load_adapter(using_will_paginate, mock_request(test: 'test'))
|
|
125
146
|
|
|
126
147
|
assert_equal expected_response_with_pagination_links_and_additional_params,
|
|
127
148
|
adapter.serializable_hash
|
|
@@ -132,7 +153,7 @@ module ActiveModelSerializers
|
|
|
132
153
|
|
|
133
154
|
adapter = load_adapter(using_kaminari(1), mock_request)
|
|
134
155
|
|
|
135
|
-
assert_equal
|
|
156
|
+
assert_equal expected_response_with_empty_collection_pagination_links, adapter.serializable_hash
|
|
136
157
|
end
|
|
137
158
|
|
|
138
159
|
def test_pagination_links_when_zero_results_will_paginate
|
|
@@ -140,7 +161,7 @@ module ActiveModelSerializers
|
|
|
140
161
|
|
|
141
162
|
adapter = load_adapter(using_will_paginate(1), mock_request)
|
|
142
163
|
|
|
143
|
-
assert_equal
|
|
164
|
+
assert_equal expected_response_with_empty_collection_pagination_links, adapter.serializable_hash
|
|
144
165
|
end
|
|
145
166
|
|
|
146
167
|
def test_last_page_pagination_links_using_kaminari
|
|
@@ -158,7 +179,28 @@ module ActiveModelSerializers
|
|
|
158
179
|
def test_not_showing_pagination_links
|
|
159
180
|
adapter = load_adapter(@array, mock_request)
|
|
160
181
|
|
|
182
|
+
assert_equal expected_response_when_unpaginatable, adapter.serializable_hash
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
def test_raises_descriptive_error_when_serialization_context_unset
|
|
186
|
+
render_options = { adapter: :json_api }
|
|
187
|
+
adapter = serializable(using_kaminari, render_options)
|
|
188
|
+
exception_class = ActiveModelSerializers::Adapter::JsonApi::PaginationLinks::MissingSerializationContextError
|
|
189
|
+
|
|
190
|
+
exception = assert_raises(exception_class) do
|
|
191
|
+
adapter.as_json
|
|
192
|
+
end
|
|
193
|
+
assert_equal exception_class, exception.class
|
|
194
|
+
assert_match(/CollectionSerializer#paginated\?/, exception.message)
|
|
195
|
+
end
|
|
196
|
+
|
|
197
|
+
def test_pagination_links_not_present_when_disabled
|
|
198
|
+
ActiveModel::Serializer.config.jsonapi_pagination_links_enabled = false
|
|
199
|
+
adapter = load_adapter(using_kaminari, mock_request)
|
|
200
|
+
|
|
161
201
|
assert_equal expected_response_without_pagination_links, adapter.serializable_hash
|
|
202
|
+
ensure
|
|
203
|
+
ActiveModel::Serializer.config.jsonapi_pagination_links_enabled = true
|
|
162
204
|
end
|
|
163
205
|
end
|
|
164
206
|
end
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require 'test_helper'
|
|
2
4
|
module ActiveModelSerializers
|
|
3
5
|
module Adapter
|
|
@@ -125,7 +127,7 @@ module ActiveModelSerializers
|
|
|
125
127
|
src: 'http://example.com/images/productivity.png',
|
|
126
128
|
author_id: nil,
|
|
127
129
|
photographer_id: '9',
|
|
128
|
-
photographer_type: '
|
|
130
|
+
photographer_type: 'Person',
|
|
129
131
|
comment_ids: %w(1 2)
|
|
130
132
|
}
|
|
131
133
|
assert_equal(expected, parsed_hash)
|
|
@@ -1,16 +1,11 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require 'test_helper'
|
|
2
4
|
|
|
3
5
|
module ActiveModelSerializers
|
|
4
6
|
module Adapter
|
|
5
7
|
class JsonApi
|
|
6
8
|
class RelationshipTest < ActiveSupport::TestCase
|
|
7
|
-
setup do
|
|
8
|
-
@blog = Blog.new(id: 1)
|
|
9
|
-
@author = Author.new(id: 1, name: 'Steve K.', blog: @blog)
|
|
10
|
-
@serializer = BlogSerializer.new(@blog)
|
|
11
|
-
ActionController::Base.cache_store.clear
|
|
12
|
-
end
|
|
13
|
-
|
|
14
9
|
def test_relationship_with_data
|
|
15
10
|
expected = {
|
|
16
11
|
data: {
|
|
@@ -18,26 +13,29 @@ module ActiveModelSerializers
|
|
|
18
13
|
type: 'blogs'
|
|
19
14
|
}
|
|
20
15
|
}
|
|
21
|
-
|
|
16
|
+
|
|
17
|
+
model_attributes = { blog: Blog.new(id: 1) }
|
|
18
|
+
relationship_name = :blog
|
|
19
|
+
model = new_model(model_attributes)
|
|
20
|
+
actual = build_serializer_and_serialize_relationship(model, relationship_name) do
|
|
21
|
+
has_one :blog
|
|
22
|
+
end
|
|
23
|
+
assert_equal(expected, actual)
|
|
22
24
|
end
|
|
23
25
|
|
|
24
26
|
def test_relationship_with_nil_model
|
|
25
|
-
@serializer = BlogSerializer.new(nil)
|
|
26
27
|
expected = { data: nil }
|
|
27
|
-
test_relationship(expected, options: { include_data: true })
|
|
28
|
-
end
|
|
29
28
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
29
|
+
model_attributes = { blog: nil }
|
|
30
|
+
relationship_name = :blog
|
|
31
|
+
model = new_model(model_attributes)
|
|
32
|
+
actual = build_serializer_and_serialize_relationship(model, relationship_name) do
|
|
33
|
+
has_one :blog
|
|
34
|
+
end
|
|
35
|
+
assert_equal(expected, actual)
|
|
34
36
|
end
|
|
35
37
|
|
|
36
38
|
def test_relationship_with_data_array
|
|
37
|
-
posts = [Post.new(id: 1), Post.new(id: 2)]
|
|
38
|
-
@serializer = ActiveModel::Serializer::CollectionSerializer.new(posts)
|
|
39
|
-
@author.posts = posts
|
|
40
|
-
@author.blog = nil
|
|
41
39
|
expected = {
|
|
42
40
|
data: [
|
|
43
41
|
{
|
|
@@ -50,110 +48,350 @@ module ActiveModelSerializers
|
|
|
50
48
|
}
|
|
51
49
|
]
|
|
52
50
|
}
|
|
53
|
-
|
|
51
|
+
|
|
52
|
+
model_attributes = { posts: [Post.new(id: 1), Post.new(id: 2)] }
|
|
53
|
+
relationship_name = :posts
|
|
54
|
+
model = new_model(model_attributes)
|
|
55
|
+
actual = build_serializer_and_serialize_relationship(model, relationship_name) do
|
|
56
|
+
has_many :posts
|
|
57
|
+
end
|
|
58
|
+
assert_equal(expected, actual)
|
|
54
59
|
end
|
|
55
60
|
|
|
56
61
|
def test_relationship_data_not_included
|
|
57
|
-
|
|
58
|
-
end
|
|
62
|
+
expected = { meta: {} }
|
|
59
63
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
64
|
+
model_attributes = { blog: :does_not_matter }
|
|
65
|
+
relationship_name = :blog
|
|
66
|
+
model = new_model(model_attributes)
|
|
67
|
+
actual = build_serializer_and_serialize_relationship(model, relationship_name) do
|
|
68
|
+
has_one :blog do
|
|
69
|
+
include_data false
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
assert_equal(expected, actual)
|
|
63
73
|
end
|
|
64
74
|
|
|
65
75
|
def test_relationship_many_links
|
|
66
|
-
links = {
|
|
67
|
-
self: 'a link',
|
|
68
|
-
related: 'another link'
|
|
69
|
-
}
|
|
70
76
|
expected = {
|
|
71
77
|
links: {
|
|
72
78
|
self: 'a link',
|
|
73
79
|
related: 'another link'
|
|
74
80
|
}
|
|
75
81
|
}
|
|
76
|
-
test_relationship(expected, links: links)
|
|
77
|
-
end
|
|
78
82
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
+
model_attributes = { blog: :does_not_matter }
|
|
84
|
+
relationship_name = :blog
|
|
85
|
+
model = new_model(model_attributes)
|
|
86
|
+
actual = build_serializer_and_serialize_relationship(model, relationship_name) do
|
|
87
|
+
has_one :blog do
|
|
88
|
+
include_data false
|
|
89
|
+
link :self, 'a link'
|
|
90
|
+
link :related, 'another link'
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
assert_equal(expected, actual)
|
|
83
94
|
end
|
|
84
95
|
|
|
85
96
|
def test_relationship_block_link_with_meta
|
|
86
|
-
links = {
|
|
87
|
-
self: proc do
|
|
88
|
-
href object.id.to_s
|
|
89
|
-
meta(id: object.id)
|
|
90
|
-
end
|
|
91
|
-
}
|
|
92
97
|
expected = {
|
|
93
98
|
links: {
|
|
94
99
|
self: {
|
|
95
|
-
href:
|
|
96
|
-
meta: { id:
|
|
100
|
+
href: '1',
|
|
101
|
+
meta: { id: 1 }
|
|
97
102
|
}
|
|
98
103
|
}
|
|
99
104
|
}
|
|
100
|
-
|
|
105
|
+
|
|
106
|
+
model_attributes = { blog: Blog.new(id: 1) }
|
|
107
|
+
relationship_name = :blog
|
|
108
|
+
model = new_model(model_attributes)
|
|
109
|
+
actual = build_serializer_and_serialize_relationship(model, relationship_name) do
|
|
110
|
+
has_one :blog do
|
|
111
|
+
include_data false
|
|
112
|
+
link :self do
|
|
113
|
+
href object.blog.id.to_s
|
|
114
|
+
meta(id: object.blog.id)
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
assert_equal(expected, actual)
|
|
101
119
|
end
|
|
102
120
|
|
|
103
121
|
def test_relationship_simple_meta
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
122
|
+
expected = { meta: { id: '1' } }
|
|
123
|
+
|
|
124
|
+
model_attributes = { blog: Blog.new(id: 1) }
|
|
125
|
+
relationship_name = :blog
|
|
126
|
+
model = new_model(model_attributes)
|
|
127
|
+
actual = build_serializer_and_serialize_relationship(model, relationship_name) do
|
|
128
|
+
has_one :blog do
|
|
129
|
+
include_data false
|
|
130
|
+
meta(id: object.blog.id.to_s)
|
|
131
|
+
end
|
|
132
|
+
end
|
|
133
|
+
assert_equal(expected, actual)
|
|
107
134
|
end
|
|
108
135
|
|
|
109
136
|
def test_relationship_block_meta
|
|
110
|
-
meta = proc do
|
|
111
|
-
{ id: object.id }
|
|
112
|
-
end
|
|
113
137
|
expected = {
|
|
114
138
|
meta: {
|
|
115
|
-
id:
|
|
139
|
+
id: 1
|
|
116
140
|
}
|
|
117
141
|
}
|
|
118
|
-
|
|
142
|
+
|
|
143
|
+
model_attributes = { blog: Blog.new(id: 1) }
|
|
144
|
+
relationship_name = :blog
|
|
145
|
+
model = new_model(model_attributes)
|
|
146
|
+
actual = build_serializer_and_serialize_relationship(model, relationship_name) do
|
|
147
|
+
has_one :blog do
|
|
148
|
+
include_data false
|
|
149
|
+
meta(id: object.blog.id)
|
|
150
|
+
end
|
|
151
|
+
end
|
|
152
|
+
assert_equal(expected, actual)
|
|
119
153
|
end
|
|
120
154
|
|
|
121
|
-
def
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
155
|
+
def test_relationship_simple_link
|
|
156
|
+
expected = {
|
|
157
|
+
data: {
|
|
158
|
+
id: '1337',
|
|
159
|
+
type: 'bios'
|
|
160
|
+
},
|
|
161
|
+
links: {
|
|
162
|
+
self: '//example.com/link_author/relationships/bio'
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
model_attributes = { bio: Bio.new(id: 1337) }
|
|
167
|
+
relationship_name = :bio
|
|
168
|
+
model = new_model(model_attributes)
|
|
169
|
+
actual = build_serializer_and_serialize_relationship(model, relationship_name) do
|
|
170
|
+
has_one :bio do
|
|
171
|
+
link :self, '//example.com/link_author/relationships/bio'
|
|
127
172
|
end
|
|
173
|
+
end
|
|
174
|
+
assert_equal(expected, actual)
|
|
175
|
+
end
|
|
128
176
|
|
|
177
|
+
def test_relationship_block_link
|
|
178
|
+
expected = {
|
|
179
|
+
data: { id: '1337', type: 'profiles' },
|
|
180
|
+
links: { related: '//example.com/profiles/1337' }
|
|
129
181
|
}
|
|
130
|
-
|
|
131
|
-
|
|
182
|
+
|
|
183
|
+
model_attributes = { profile: Profile.new(id: 1337) }
|
|
184
|
+
relationship_name = :profile
|
|
185
|
+
model = new_model(model_attributes)
|
|
186
|
+
actual = build_serializer_and_serialize_relationship(model, relationship_name) do
|
|
187
|
+
has_one :profile do
|
|
188
|
+
id = object.profile.id
|
|
189
|
+
link :related do
|
|
190
|
+
"//example.com/profiles/#{id}" if id != 123
|
|
191
|
+
end
|
|
192
|
+
end
|
|
132
193
|
end
|
|
194
|
+
assert_equal(expected, actual)
|
|
195
|
+
end
|
|
196
|
+
|
|
197
|
+
def test_relationship_with_everything
|
|
133
198
|
expected = {
|
|
134
|
-
data: {
|
|
135
|
-
id: '1',
|
|
136
|
-
type: 'blogs'
|
|
137
|
-
},
|
|
199
|
+
data: [{ id: '1337', type: 'likes' }],
|
|
138
200
|
links: {
|
|
139
|
-
self: 'a link',
|
|
140
201
|
related: {
|
|
141
|
-
href: '
|
|
202
|
+
href: '//example.com/likes/1337',
|
|
203
|
+
meta: { ids: '1337' }
|
|
142
204
|
}
|
|
143
205
|
},
|
|
144
|
-
meta: {
|
|
145
|
-
|
|
206
|
+
meta: { liked: true }
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
model_attributes = { likes: [Like.new(id: 1337)] }
|
|
210
|
+
relationship_name = :likes
|
|
211
|
+
model = new_model(model_attributes)
|
|
212
|
+
actual = build_serializer_and_serialize_relationship(model, relationship_name) do
|
|
213
|
+
has_many :likes do
|
|
214
|
+
link :related do
|
|
215
|
+
ids = object.likes.map(&:id).join(',')
|
|
216
|
+
href "//example.com/likes/#{ids}"
|
|
217
|
+
meta ids: ids
|
|
218
|
+
end
|
|
219
|
+
meta liked: object.likes.any?
|
|
220
|
+
end
|
|
221
|
+
end
|
|
222
|
+
assert_equal(expected, actual)
|
|
223
|
+
end
|
|
224
|
+
|
|
225
|
+
def test_relationship_nil_link
|
|
226
|
+
expected = {
|
|
227
|
+
data: { id: '123', type: 'profiles' }
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
model_attributes = { profile: Profile.new(id: 123) }
|
|
231
|
+
relationship_name = :profile
|
|
232
|
+
model = new_model(model_attributes)
|
|
233
|
+
actual = build_serializer_and_serialize_relationship(model, relationship_name) do
|
|
234
|
+
has_one :profile do
|
|
235
|
+
id = object.profile.id
|
|
236
|
+
link :related do
|
|
237
|
+
"//example.com/profiles/#{id}" if id != 123
|
|
238
|
+
end
|
|
239
|
+
end
|
|
240
|
+
end
|
|
241
|
+
assert_equal(expected, actual)
|
|
242
|
+
end
|
|
243
|
+
|
|
244
|
+
def test_relationship_block_link_href
|
|
245
|
+
expected = {
|
|
246
|
+
data: [{ id: '1337', type: 'locations' }],
|
|
247
|
+
links: {
|
|
248
|
+
related: { href: '//example.com/locations/1337' }
|
|
146
249
|
}
|
|
147
250
|
}
|
|
148
|
-
|
|
251
|
+
|
|
252
|
+
model_attributes = { locations: [Location.new(id: 1337)] }
|
|
253
|
+
relationship_name = :locations
|
|
254
|
+
model = new_model(model_attributes)
|
|
255
|
+
actual = build_serializer_and_serialize_relationship(model, relationship_name) do
|
|
256
|
+
has_many :locations do
|
|
257
|
+
link :related do
|
|
258
|
+
ids = object.locations.map(&:id).join(',')
|
|
259
|
+
href "//example.com/locations/#{ids}"
|
|
260
|
+
end
|
|
261
|
+
end
|
|
262
|
+
end
|
|
263
|
+
assert_equal(expected, actual)
|
|
264
|
+
end
|
|
265
|
+
|
|
266
|
+
def test_relationship_block_link_href_and_meta
|
|
267
|
+
expected = {
|
|
268
|
+
data: [{ id: '1337', type: 'posts' }],
|
|
269
|
+
links: {
|
|
270
|
+
related: {
|
|
271
|
+
href: '//example.com/posts/1337',
|
|
272
|
+
meta: { ids: '1337' }
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
model_attributes = { posts: [Post.new(id: 1337, comments: [], author: nil)] }
|
|
278
|
+
relationship_name = :posts
|
|
279
|
+
model = new_model(model_attributes)
|
|
280
|
+
actual = build_serializer_and_serialize_relationship(model, relationship_name) do
|
|
281
|
+
has_many :posts do
|
|
282
|
+
link :related do
|
|
283
|
+
ids = object.posts.map(&:id).join(',')
|
|
284
|
+
href "//example.com/posts/#{ids}"
|
|
285
|
+
meta ids: ids
|
|
286
|
+
end
|
|
287
|
+
end
|
|
288
|
+
end
|
|
289
|
+
assert_equal(expected, actual)
|
|
290
|
+
end
|
|
291
|
+
|
|
292
|
+
def test_relationship_block_link_meta
|
|
293
|
+
expected = {
|
|
294
|
+
data: [{ id: '1337', type: 'comments' }],
|
|
295
|
+
links: {
|
|
296
|
+
self: {
|
|
297
|
+
meta: { ids: [1] }
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
model_attributes = { comments: [Comment.new(id: 1337)] }
|
|
303
|
+
relationship_name = :comments
|
|
304
|
+
model = new_model(model_attributes)
|
|
305
|
+
actual = build_serializer_and_serialize_relationship(model, relationship_name) do
|
|
306
|
+
has_many :comments do
|
|
307
|
+
link :self do
|
|
308
|
+
meta ids: [1]
|
|
309
|
+
end
|
|
310
|
+
end
|
|
311
|
+
end
|
|
312
|
+
assert_equal(expected, actual)
|
|
313
|
+
end
|
|
314
|
+
|
|
315
|
+
def test_relationship_meta
|
|
316
|
+
expected = {
|
|
317
|
+
data: [{ id: 'from-serializer-method', type: 'roles' }],
|
|
318
|
+
meta: { count: 1 }
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
model_attributes = { roles: [Role.new(id: 'from-record')] }
|
|
322
|
+
relationship_name = :roles
|
|
323
|
+
model = new_model(model_attributes)
|
|
324
|
+
actual = build_serializer_and_serialize_relationship(model, relationship_name) do
|
|
325
|
+
has_many :roles do |serializer|
|
|
326
|
+
meta count: object.roles.count
|
|
327
|
+
serializer.cached_roles
|
|
328
|
+
end
|
|
329
|
+
def cached_roles
|
|
330
|
+
[
|
|
331
|
+
Role.new(id: 'from-serializer-method')
|
|
332
|
+
]
|
|
333
|
+
end
|
|
334
|
+
end
|
|
335
|
+
assert_equal(expected, actual)
|
|
336
|
+
end
|
|
337
|
+
|
|
338
|
+
def test_relationship_not_including_data
|
|
339
|
+
expected = {
|
|
340
|
+
links: { self: '//example.com/link_author/relationships/blog' }
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
model_attributes = { blog: Object }
|
|
344
|
+
relationship_name = :blog
|
|
345
|
+
model = new_model(model_attributes)
|
|
346
|
+
model.define_singleton_method(:read_attribute_for_serialization) do |attr|
|
|
347
|
+
fail 'should not be called' if attr == :blog
|
|
348
|
+
super(attr)
|
|
349
|
+
end
|
|
350
|
+
assert_nothing_raised do
|
|
351
|
+
actual = build_serializer_and_serialize_relationship(model, relationship_name) do
|
|
352
|
+
has_one :blog do
|
|
353
|
+
link :self, '//example.com/link_author/relationships/blog'
|
|
354
|
+
include_data false
|
|
355
|
+
end
|
|
356
|
+
end
|
|
357
|
+
assert_equal(expected, actual)
|
|
358
|
+
end
|
|
359
|
+
end
|
|
360
|
+
|
|
361
|
+
def test_relationship_including_data_explicit
|
|
362
|
+
expected = {
|
|
363
|
+
data: { id: '1337', type: 'authors' },
|
|
364
|
+
meta: { name: 'Dan Brown' }
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
model_attributes = { reviewer: Author.new(id: 1337) }
|
|
368
|
+
relationship_name = :reviewer
|
|
369
|
+
model = new_model(model_attributes)
|
|
370
|
+
actual = build_serializer_and_serialize_relationship(model, relationship_name) do
|
|
371
|
+
belongs_to :reviewer do
|
|
372
|
+
meta name: 'Dan Brown'
|
|
373
|
+
include_data true
|
|
374
|
+
end
|
|
375
|
+
end
|
|
376
|
+
assert_equal(expected, actual)
|
|
149
377
|
end
|
|
150
378
|
|
|
151
379
|
private
|
|
152
380
|
|
|
153
|
-
def
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
381
|
+
def build_serializer_and_serialize_relationship(model, relationship_name, &block)
|
|
382
|
+
serializer_class = Class.new(ActiveModel::Serializer, &block)
|
|
383
|
+
hash = serializable(model, serializer: serializer_class, adapter: :json_api).serializable_hash
|
|
384
|
+
hash[:data][:relationships][relationship_name]
|
|
385
|
+
end
|
|
386
|
+
|
|
387
|
+
def new_model(model_attributes)
|
|
388
|
+
Class.new(ActiveModelSerializers::Model) do
|
|
389
|
+
attributes(*model_attributes.keys)
|
|
390
|
+
|
|
391
|
+
def self.name
|
|
392
|
+
'TestModel'
|
|
393
|
+
end
|
|
394
|
+
end.new(model_attributes)
|
|
157
395
|
end
|
|
158
396
|
end
|
|
159
397
|
end
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require 'test_helper'
|
|
2
4
|
|
|
3
5
|
module ActiveModel
|
|
@@ -68,9 +70,9 @@ module ActiveModel
|
|
|
68
70
|
adapter: :json_api
|
|
69
71
|
).serializable_hash
|
|
70
72
|
expected = {
|
|
71
|
-
:
|
|
72
|
-
{ :
|
|
73
|
-
{ :
|
|
73
|
+
data: [
|
|
74
|
+
{ id: '1337', type: 'posts', meta: { :"comments-count" => 0 } },
|
|
75
|
+
{ id: '1339', type: 'posts', meta: { :"comments-count" => 1 } }
|
|
74
76
|
]
|
|
75
77
|
}
|
|
76
78
|
assert_equal(expected, hash)
|