active_model_serializers 0.10.0 → 0.10.13
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/CHANGELOG.md +239 -2
- data/README.md +171 -34
- data/lib/action_controller/serialization.rb +23 -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 +48 -13
- data/lib/active_model/serializer/{caching.rb → concerns/caching.rb} +89 -117
- 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 +3 -1
- 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 +130 -65
- data/lib/active_model/serializer/version.rb +3 -1
- data/lib/active_model/serializer.rb +321 -86
- data/lib/active_model_serializers/adapter/attributes.rb +17 -57
- 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 +52 -20
- 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/caching.rb +26 -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
- metadata +104 -296
- data/.github/ISSUE_TEMPLATE.md +0 -29
- data/.github/PULL_REQUEST_TEMPLATE.md +0 -15
- data/.gitignore +0 -35
- data/.rubocop.yml +0 -104
- data/.rubocop_todo.yml +0 -167
- data/.simplecov +0 -110
- data/.travis.yml +0 -43
- data/CONTRIBUTING.md +0 -105
- data/Gemfile +0 -53
- data/Rakefile +0 -103
- data/active_model_serializers.gemspec +0 -66
- data/appveyor.yml +0 -24
- data/bin/bench +0 -171
- data/bin/bench_regression +0 -316
- data/bin/serve_benchmark +0 -39
- data/docs/ARCHITECTURE.md +0 -126
- data/docs/README.md +0 -40
- data/docs/STYLE.md +0 -58
- data/docs/general/adapters.md +0 -245
- data/docs/general/caching.md +0 -52
- data/docs/general/configuration_options.md +0 -100
- data/docs/general/deserialization.md +0 -100
- data/docs/general/getting_started.md +0 -133
- data/docs/general/instrumentation.md +0 -40
- data/docs/general/key_transforms.md +0 -40
- data/docs/general/logging.md +0 -14
- data/docs/general/rendering.md +0 -255
- data/docs/general/serializers.md +0 -372
- data/docs/how-open-source-maintained.jpg +0 -0
- data/docs/howto/add_pagination_links.md +0 -139
- data/docs/howto/add_root_key.md +0 -51
- data/docs/howto/outside_controller_use.md +0 -58
- data/docs/howto/passing_arbitrary_options.md +0 -27
- data/docs/howto/serialize_poro.md +0 -32
- data/docs/howto/test.md +0 -152
- data/docs/integrations/ember-and-json-api.md +0 -112
- data/docs/integrations/grape.md +0 -19
- data/docs/jsonapi/errors.md +0 -56
- data/docs/jsonapi/schema/schema.json +0 -366
- data/docs/jsonapi/schema.md +0 -151
- data/docs/rfcs/0000-namespace.md +0 -106
- data/docs/rfcs/template.md +0 -15
- 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/action_controller/adapter_selector_test.rb +0 -53
- data/test/action_controller/explicit_serializer_test.rb +0 -134
- data/test/action_controller/json/include_test.rb +0 -167
- data/test/action_controller/json_api/deserialization_test.rb +0 -112
- data/test/action_controller/json_api/errors_test.rb +0 -41
- data/test/action_controller/json_api/linked_test.rb +0 -197
- data/test/action_controller/json_api/pagination_test.rb +0 -116
- data/test/action_controller/json_api/transform_test.rb +0 -181
- data/test/action_controller/serialization_scope_name_test.rb +0 -229
- data/test/action_controller/serialization_test.rb +0 -469
- data/test/active_model_serializers/adapter_for_test.rb +0 -208
- data/test/active_model_serializers/json_pointer_test.rb +0 -20
- data/test/active_model_serializers/key_transform_test.rb +0 -263
- data/test/active_model_serializers/logging_test.rb +0 -77
- data/test/active_model_serializers/model_test.rb +0 -9
- data/test/active_model_serializers/railtie_test_isolated.rb +0 -63
- data/test/active_model_serializers/serialization_context_test_isolated.rb +0 -58
- data/test/active_model_serializers/test/schema_test.rb +0 -130
- data/test/active_model_serializers/test/serializer_test.rb +0 -62
- data/test/active_record_test.rb +0 -9
- data/test/adapter/deprecation_test.rb +0 -100
- data/test/adapter/json/belongs_to_test.rb +0 -45
- data/test/adapter/json/collection_test.rb +0 -90
- data/test/adapter/json/has_many_test.rb +0 -45
- data/test/adapter/json/transform_test.rb +0 -93
- data/test/adapter/json_api/belongs_to_test.rb +0 -155
- data/test/adapter/json_api/collection_test.rb +0 -95
- data/test/adapter/json_api/errors_test.rb +0 -78
- data/test/adapter/json_api/fields_test.rb +0 -87
- data/test/adapter/json_api/has_many_embed_ids_test.rb +0 -43
- data/test/adapter/json_api/has_many_explicit_serializer_test.rb +0 -96
- data/test/adapter/json_api/has_many_test.rb +0 -144
- data/test/adapter/json_api/has_one_test.rb +0 -80
- data/test/adapter/json_api/json_api_test.rb +0 -35
- data/test/adapter/json_api/linked_test.rb +0 -392
- data/test/adapter/json_api/links_test.rb +0 -93
- data/test/adapter/json_api/pagination_links_test.rb +0 -166
- data/test/adapter/json_api/parse_test.rb +0 -137
- data/test/adapter/json_api/relationship_test.rb +0 -161
- data/test/adapter/json_api/relationships_test.rb +0 -199
- data/test/adapter/json_api/resource_identifier_test.rb +0 -85
- data/test/adapter/json_api/resource_meta_test.rb +0 -100
- data/test/adapter/json_api/toplevel_jsonapi_test.rb +0 -82
- data/test/adapter/json_api/transform_test.rb +0 -502
- data/test/adapter/json_api/type_test.rb +0 -61
- data/test/adapter/json_test.rb +0 -45
- data/test/adapter/null_test.rb +0 -23
- data/test/adapter/polymorphic_test.rb +0 -171
- data/test/adapter_test.rb +0 -67
- data/test/array_serializer_test.rb +0 -22
- data/test/benchmark/app.rb +0 -65
- data/test/benchmark/benchmarking_support.rb +0 -67
- data/test/benchmark/bm_caching.rb +0 -119
- data/test/benchmark/bm_transform.rb +0 -34
- data/test/benchmark/config.ru +0 -3
- data/test/benchmark/controllers.rb +0 -84
- data/test/benchmark/fixtures.rb +0 -219
- data/test/cache_test.rb +0 -485
- data/test/collection_serializer_test.rb +0 -110
- data/test/fixtures/active_record.rb +0 -78
- data/test/fixtures/poro.rb +0 -282
- data/test/generators/scaffold_controller_generator_test.rb +0 -24
- data/test/generators/serializer_generator_test.rb +0 -57
- data/test/grape_test.rb +0 -82
- 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
- data/test/lint_test.rb +0 -49
- data/test/logger_test.rb +0 -18
- data/test/poro_test.rb +0 -9
- data/test/serializable_resource_test.rb +0 -83
- data/test/serializers/association_macros_test.rb +0 -36
- data/test/serializers/associations_test.rb +0 -295
- data/test/serializers/attribute_test.rb +0 -151
- data/test/serializers/attributes_test.rb +0 -52
- data/test/serializers/caching_configuration_test_isolated.rb +0 -170
- data/test/serializers/configuration_test.rb +0 -32
- data/test/serializers/fieldset_test.rb +0 -14
- data/test/serializers/meta_test.rb +0 -196
- data/test/serializers/options_test.rb +0 -21
- data/test/serializers/read_attribute_for_serialization_test.rb +0 -79
- data/test/serializers/root_test.rb +0 -21
- data/test/serializers/serialization_test.rb +0 -55
- data/test/serializers/serializer_for_test.rb +0 -134
- data/test/support/custom_schemas/active_model_serializers/test/schema_test/my/index.json +0 -6
- data/test/support/isolated_unit.rb +0 -79
- data/test/support/rails5_shims.rb +0 -47
- data/test/support/rails_app.rb +0 -45
- data/test/support/schemas/active_model_serializers/test/schema_test/my/index.json +0 -6
- data/test/support/schemas/active_model_serializers/test/schema_test/my/show.json +0 -6
- data/test/support/schemas/custom/show.json +0 -7
- data/test/support/schemas/hyper_schema.json +0 -93
- data/test/support/schemas/render_using_json_api.json +0 -43
- data/test/support/schemas/simple_json_pointers.json +0 -10
- data/test/support/serialization_testing.rb +0 -53
- data/test/test_helper.rb +0 -57
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'case_transform'
|
|
2
4
|
|
|
3
5
|
module ActiveModelSerializers
|
|
4
6
|
module Adapter
|
|
@@ -8,6 +10,40 @@ module ActiveModelSerializers
|
|
|
8
10
|
ActiveModelSerializers::Adapter.register(subclass)
|
|
9
11
|
end
|
|
10
12
|
|
|
13
|
+
# Sets the default transform for the adapter.
|
|
14
|
+
#
|
|
15
|
+
# @return [Symbol] the default transform for the adapter
|
|
16
|
+
def self.default_key_transform
|
|
17
|
+
:unaltered
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# Determines the transform to use in order of precedence:
|
|
21
|
+
# adapter option, global config, adapter default.
|
|
22
|
+
#
|
|
23
|
+
# @param options [Object]
|
|
24
|
+
# @return [Symbol] the transform to use
|
|
25
|
+
def self.transform(options)
|
|
26
|
+
return options[:key_transform] if options && options[:key_transform]
|
|
27
|
+
ActiveModelSerializers.config.key_transform || default_key_transform
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# Transforms the casing of the supplied value.
|
|
31
|
+
#
|
|
32
|
+
# @param value [Object] the value to be transformed
|
|
33
|
+
# @param options [Object] serializable resource options
|
|
34
|
+
# @return [Symbol] the default transform for the adapter
|
|
35
|
+
def self.transform_key_casing!(value, options)
|
|
36
|
+
CaseTransform.send(transform(options), value)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def self.cache_key
|
|
40
|
+
@cache_key ||= ActiveModelSerializers::Adapter.registered_name(self)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def self.fragment_cache(cached_hash, non_cached_hash)
|
|
44
|
+
non_cached_hash.merge cached_hash
|
|
45
|
+
end
|
|
46
|
+
|
|
11
47
|
attr_reader :serializer, :instance_options
|
|
12
48
|
|
|
13
49
|
def initialize(serializer, options = {})
|
|
@@ -15,10 +51,6 @@ module ActiveModelSerializers
|
|
|
15
51
|
@instance_options = options
|
|
16
52
|
end
|
|
17
53
|
|
|
18
|
-
def cached_name
|
|
19
|
-
@cached_name ||= self.class.name.demodulize.underscore
|
|
20
|
-
end
|
|
21
|
-
|
|
22
54
|
# Subclasses that implement this method must first call
|
|
23
55
|
# options = serialization_options(options)
|
|
24
56
|
def serializable_hash(_options = nil)
|
|
@@ -29,14 +61,12 @@ module ActiveModelSerializers
|
|
|
29
61
|
serializable_hash(options)
|
|
30
62
|
end
|
|
31
63
|
|
|
32
|
-
def
|
|
33
|
-
|
|
64
|
+
def cache_key
|
|
65
|
+
self.class.cache_key
|
|
34
66
|
end
|
|
35
67
|
|
|
36
|
-
def
|
|
37
|
-
|
|
38
|
-
yield
|
|
39
|
-
end
|
|
68
|
+
def fragment_cache(cached_hash, non_cached_hash)
|
|
69
|
+
self.class.fragment_cache(cached_hash, non_cached_hash)
|
|
40
70
|
end
|
|
41
71
|
|
|
42
72
|
private
|
|
@@ -50,34 +80,6 @@ module ActiveModelSerializers
|
|
|
50
80
|
def root
|
|
51
81
|
serializer.json_key.to_sym if serializer.json_key
|
|
52
82
|
end
|
|
53
|
-
|
|
54
|
-
class << self
|
|
55
|
-
# Sets the default transform for the adapter.
|
|
56
|
-
#
|
|
57
|
-
# @return [Symbol] the default transform for the adapter
|
|
58
|
-
def default_key_transform
|
|
59
|
-
:unaltered
|
|
60
|
-
end
|
|
61
|
-
|
|
62
|
-
# Determines the transform to use in order of precedence:
|
|
63
|
-
# adapter option, global config, adapter default.
|
|
64
|
-
#
|
|
65
|
-
# @param options [Object]
|
|
66
|
-
# @return [Symbol] the transform to use
|
|
67
|
-
def transform(options)
|
|
68
|
-
return options[:key_transform] if options && options[:key_transform]
|
|
69
|
-
ActiveModelSerializers.config.key_transform || default_key_transform
|
|
70
|
-
end
|
|
71
|
-
|
|
72
|
-
# Transforms the casing of the supplied value.
|
|
73
|
-
#
|
|
74
|
-
# @param value [Object] the value to be transformed
|
|
75
|
-
# @param options [Object] serializable resource options
|
|
76
|
-
# @return [Symbol] the default transform for the adapter
|
|
77
|
-
def transform_key_casing!(value, options)
|
|
78
|
-
KeyTransform.send(transform(options), value)
|
|
79
|
-
end
|
|
80
|
-
end
|
|
81
83
|
end
|
|
82
84
|
end
|
|
83
85
|
end
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module ActiveModelSerializers
|
|
2
4
|
module Adapter
|
|
3
5
|
class JsonApi
|
|
@@ -189,7 +191,7 @@ module ActiveModelSerializers
|
|
|
189
191
|
|
|
190
192
|
polymorphic = (options[:polymorphic] || []).include?(assoc_name.to_sym)
|
|
191
193
|
if polymorphic
|
|
192
|
-
hash["#{prefix_key}_type".to_sym] = assoc_data.present? ? assoc_data['type'] : nil
|
|
194
|
+
hash["#{prefix_key}_type".to_sym] = assoc_data.present? ? assoc_data['type'].classify : nil
|
|
193
195
|
end
|
|
194
196
|
|
|
195
197
|
hash
|
|
@@ -205,7 +207,7 @@ module ActiveModelSerializers
|
|
|
205
207
|
# @api private
|
|
206
208
|
def transform_keys(hash, options)
|
|
207
209
|
transform = options[:key_transform] || :underscore
|
|
208
|
-
|
|
210
|
+
CaseTransform.send(transform, hash)
|
|
209
211
|
end
|
|
210
212
|
end
|
|
211
213
|
end
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module ActiveModelSerializers
|
|
2
4
|
module Adapter
|
|
3
5
|
class JsonApi
|
|
@@ -71,7 +73,7 @@ module ActiveModelSerializers
|
|
|
71
73
|
hash[:href] = @href if defined?(@href)
|
|
72
74
|
hash[:meta] = @meta if defined?(@meta)
|
|
73
75
|
|
|
74
|
-
hash
|
|
76
|
+
hash.any? ? hash : nil
|
|
75
77
|
end
|
|
76
78
|
|
|
77
79
|
protected
|
|
@@ -1,7 +1,10 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module ActiveModelSerializers
|
|
2
4
|
module Adapter
|
|
3
5
|
class JsonApi < Base
|
|
4
6
|
class PaginationLinks
|
|
7
|
+
MissingSerializationContextError = Class.new(KeyError)
|
|
5
8
|
FIRST_PAGE = 1
|
|
6
9
|
|
|
7
10
|
attr_reader :collection, :context
|
|
@@ -9,16 +12,23 @@ module ActiveModelSerializers
|
|
|
9
12
|
def initialize(collection, adapter_options)
|
|
10
13
|
@collection = collection
|
|
11
14
|
@adapter_options = adapter_options
|
|
12
|
-
@context = adapter_options.fetch(:serialization_context)
|
|
15
|
+
@context = adapter_options.fetch(:serialization_context) do
|
|
16
|
+
fail MissingSerializationContextError, <<-EOF.freeze
|
|
17
|
+
JsonApi::PaginationLinks requires a ActiveModelSerializers::SerializationContext.
|
|
18
|
+
Please pass a ':serialization_context' option or
|
|
19
|
+
override CollectionSerializer#paginated? to return 'false'.
|
|
20
|
+
EOF
|
|
21
|
+
end
|
|
13
22
|
end
|
|
14
23
|
|
|
15
24
|
def as_json
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
25
|
+
{
|
|
26
|
+
self: location_url,
|
|
27
|
+
first: first_page_url,
|
|
28
|
+
prev: prev_page_url,
|
|
29
|
+
next: next_page_url,
|
|
30
|
+
last: last_page_url
|
|
31
|
+
}
|
|
22
32
|
end
|
|
23
33
|
|
|
24
34
|
protected
|
|
@@ -27,25 +37,43 @@ module ActiveModelSerializers
|
|
|
27
37
|
|
|
28
38
|
private
|
|
29
39
|
|
|
30
|
-
def
|
|
31
|
-
|
|
40
|
+
def location_url
|
|
41
|
+
url_for_page(collection.current_page)
|
|
42
|
+
end
|
|
32
43
|
|
|
33
|
-
|
|
34
|
-
|
|
44
|
+
def first_page_url
|
|
45
|
+
url_for_page(1)
|
|
46
|
+
end
|
|
35
47
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
48
|
+
def last_page_url
|
|
49
|
+
if collection.total_pages == 0
|
|
50
|
+
url_for_page(FIRST_PAGE)
|
|
51
|
+
else
|
|
52
|
+
url_for_page(collection.total_pages)
|
|
53
|
+
end
|
|
54
|
+
end
|
|
40
55
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
56
|
+
def prev_page_url
|
|
57
|
+
return nil if collection.current_page == FIRST_PAGE
|
|
58
|
+
if collection.current_page > collection.total_pages
|
|
59
|
+
return url_for_page(collection.total_pages)
|
|
45
60
|
end
|
|
61
|
+
url_for_page(collection.current_page - FIRST_PAGE)
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def next_page_url
|
|
65
|
+
return nil if collection.total_pages == 0 ||
|
|
66
|
+
collection.current_page >= collection.total_pages
|
|
67
|
+
url_for_page(collection.next_page)
|
|
46
68
|
end
|
|
47
69
|
|
|
48
|
-
def
|
|
70
|
+
def url_for_page(number)
|
|
71
|
+
params = query_parameters.dup
|
|
72
|
+
params[:page] = { size: per_page, number: number }
|
|
73
|
+
"#{url(adapter_options)}?#{params.to_query}"
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def url(options = {})
|
|
49
77
|
@url ||= options.fetch(:links, {}).fetch(:self, nil) || request_url
|
|
50
78
|
end
|
|
51
79
|
|
|
@@ -56,6 +84,10 @@ module ActiveModelSerializers
|
|
|
56
84
|
def query_parameters
|
|
57
85
|
@query_parameters ||= context.query_parameters
|
|
58
86
|
end
|
|
87
|
+
|
|
88
|
+
def per_page
|
|
89
|
+
@per_page ||= collection.try(:per_page) || collection.try(:limit_value) || collection.size
|
|
90
|
+
end
|
|
59
91
|
end
|
|
60
92
|
end
|
|
61
93
|
end
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module ActiveModelSerializers
|
|
2
4
|
module Adapter
|
|
3
5
|
class JsonApi
|
|
@@ -5,47 +7,99 @@ module ActiveModelSerializers
|
|
|
5
7
|
# {http://jsonapi.org/format/#document-resource-object-related-resource-links Document Resource Object Related Resource Links}
|
|
6
8
|
# {http://jsonapi.org/format/#document-links Document Links}
|
|
7
9
|
# {http://jsonapi.org/format/#document-resource-object-linkage Document Resource Relationship Linkage}
|
|
8
|
-
# {http://jsonapi.org/format/#document-meta
|
|
9
|
-
def initialize(parent_serializer,
|
|
10
|
-
@
|
|
11
|
-
@
|
|
12
|
-
@association_options = args.fetch(:options, {})
|
|
10
|
+
# {http://jsonapi.org/format/#document-meta Document Meta}
|
|
11
|
+
def initialize(parent_serializer, serializable_resource_options, association)
|
|
12
|
+
@parent_serializer = parent_serializer
|
|
13
|
+
@association = association
|
|
13
14
|
@serializable_resource_options = serializable_resource_options
|
|
14
|
-
@data = data_for(serializer)
|
|
15
|
-
@links = args.fetch(:links, {}).each_with_object({}) do |(key, value), hash|
|
|
16
|
-
hash[key] = ActiveModelSerializers::Adapter::JsonApi::Link.new(parent_serializer, value).as_json
|
|
17
|
-
end
|
|
18
|
-
meta = args.fetch(:meta, nil)
|
|
19
|
-
@meta = meta.respond_to?(:call) ? parent_serializer.instance_eval(&meta) : meta
|
|
20
15
|
end
|
|
21
16
|
|
|
22
17
|
def as_json
|
|
23
18
|
hash = {}
|
|
24
|
-
|
|
25
|
-
|
|
19
|
+
|
|
20
|
+
hash[:data] = data_for(association) if association.include_data?
|
|
21
|
+
|
|
22
|
+
links = links_for(association)
|
|
26
23
|
hash[:links] = links if links.any?
|
|
27
|
-
|
|
24
|
+
|
|
25
|
+
meta = meta_for(association)
|
|
28
26
|
hash[:meta] = meta if meta
|
|
27
|
+
hash[:meta] = {} if hash.empty?
|
|
29
28
|
|
|
30
29
|
hash
|
|
31
30
|
end
|
|
32
31
|
|
|
33
32
|
protected
|
|
34
33
|
|
|
35
|
-
attr_reader :
|
|
36
|
-
:association_options, :links, :meta
|
|
34
|
+
attr_reader :parent_serializer, :serializable_resource_options, :association
|
|
37
35
|
|
|
38
36
|
private
|
|
39
37
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
38
|
+
# TODO(BF): Avoid db hit on belong_to_ releationship by using foreign_key on self
|
|
39
|
+
def data_for(association)
|
|
40
|
+
if association.collection?
|
|
41
|
+
data_for_many(association)
|
|
42
|
+
else
|
|
43
|
+
data_for_one(association)
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def data_for_one(association)
|
|
48
|
+
if belongs_to_id_on_self?(association)
|
|
49
|
+
id = parent_serializer.read_attribute_for_serialization(association.reflection.foreign_key)
|
|
50
|
+
type =
|
|
51
|
+
if association.polymorphic?
|
|
52
|
+
# We can't infer resource type for polymorphic relationships from the serializer.
|
|
53
|
+
# We can ONLY know a polymorphic resource type by inspecting each resource.
|
|
54
|
+
association.lazy_association.serializer.json_key
|
|
55
|
+
else
|
|
56
|
+
association.reflection.type.to_s
|
|
57
|
+
end
|
|
58
|
+
ResourceIdentifier.for_type_with_id(type, id, serializable_resource_options)
|
|
59
|
+
else
|
|
60
|
+
# TODO(BF): Process relationship without evaluating lazy_association
|
|
61
|
+
serializer = association.lazy_association.serializer
|
|
62
|
+
if (virtual_value = association.virtual_value)
|
|
63
|
+
virtual_value
|
|
64
|
+
elsif serializer && association.object
|
|
65
|
+
ResourceIdentifier.new(serializer, serializable_resource_options).as_json
|
|
66
|
+
else
|
|
67
|
+
nil
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def data_for_many(association)
|
|
73
|
+
# TODO(BF): Process relationship without evaluating lazy_association
|
|
74
|
+
collection_serializer = association.lazy_association.serializer
|
|
75
|
+
if collection_serializer.respond_to?(:each)
|
|
76
|
+
collection_serializer.map do |serializer|
|
|
77
|
+
ResourceIdentifier.new(serializer, serializable_resource_options).as_json
|
|
78
|
+
end
|
|
79
|
+
elsif (virtual_value = association.virtual_value)
|
|
80
|
+
virtual_value
|
|
81
|
+
else
|
|
82
|
+
[]
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def links_for(association)
|
|
87
|
+
association.links.each_with_object({}) do |(key, value), hash|
|
|
88
|
+
result = Link.new(parent_serializer, value).as_json
|
|
89
|
+
hash[key] = result if result
|
|
47
90
|
end
|
|
48
91
|
end
|
|
92
|
+
|
|
93
|
+
def meta_for(association)
|
|
94
|
+
meta = association.meta
|
|
95
|
+
meta.respond_to?(:call) ? parent_serializer.instance_eval(&meta) : meta
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
def belongs_to_id_on_self?(association)
|
|
99
|
+
parent_serializer.config.jsonapi_use_foreign_key_on_belongs_to_relationship &&
|
|
100
|
+
association.belongs_to? &&
|
|
101
|
+
parent_serializer.object.respond_to?(association.reflection.foreign_key)
|
|
102
|
+
end
|
|
49
103
|
end
|
|
50
104
|
end
|
|
51
105
|
end
|
|
@@ -1,16 +1,51 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module ActiveModelSerializers
|
|
2
4
|
module Adapter
|
|
3
5
|
class JsonApi
|
|
4
6
|
class ResourceIdentifier
|
|
7
|
+
def self.type_for(serializer, serializer_type = nil, transform_options = {})
|
|
8
|
+
raw_type = serializer_type ? serializer_type : raw_type_from_serializer_object(serializer.object)
|
|
9
|
+
JsonApi.send(:transform_key_casing!, raw_type, transform_options)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def self.for_type_with_id(type, id, options)
|
|
13
|
+
type = inflect_type(type)
|
|
14
|
+
type = type_for(:no_class_needed, type, options)
|
|
15
|
+
if id.blank?
|
|
16
|
+
nil
|
|
17
|
+
else
|
|
18
|
+
{ id: id.to_s, type: type }
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def self.raw_type_from_serializer_object(object)
|
|
23
|
+
class_name = object.class.name # should use model_name
|
|
24
|
+
raw_type = class_name.underscore
|
|
25
|
+
raw_type = inflect_type(raw_type)
|
|
26
|
+
raw_type
|
|
27
|
+
.gsub!('/'.freeze, ActiveModelSerializers.config.jsonapi_namespace_separator)
|
|
28
|
+
raw_type
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def self.inflect_type(type)
|
|
32
|
+
singularize = ActiveModelSerializers.config.jsonapi_resource_type == :singular
|
|
33
|
+
inflection = singularize ? :singularize : :pluralize
|
|
34
|
+
ActiveSupport::Inflector.public_send(inflection, type)
|
|
35
|
+
end
|
|
36
|
+
|
|
5
37
|
# {http://jsonapi.org/format/#document-resource-identifier-objects Resource Identifier Objects}
|
|
6
38
|
def initialize(serializer, options)
|
|
7
39
|
@id = id_for(serializer)
|
|
8
|
-
@type =
|
|
9
|
-
options)
|
|
40
|
+
@type = type_for(serializer, options)
|
|
10
41
|
end
|
|
11
42
|
|
|
12
43
|
def as_json
|
|
13
|
-
|
|
44
|
+
if id.blank?
|
|
45
|
+
{ type: type }
|
|
46
|
+
else
|
|
47
|
+
{ id: id.to_s, type: type }
|
|
48
|
+
end
|
|
14
49
|
end
|
|
15
50
|
|
|
16
51
|
protected
|
|
@@ -19,13 +54,9 @@ module ActiveModelSerializers
|
|
|
19
54
|
|
|
20
55
|
private
|
|
21
56
|
|
|
22
|
-
def type_for(serializer)
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
serializer.object.class.model_name.singular
|
|
26
|
-
else
|
|
27
|
-
serializer.object.class.model_name.plural
|
|
28
|
-
end
|
|
57
|
+
def type_for(serializer, transform_options)
|
|
58
|
+
serializer_type = serializer._type
|
|
59
|
+
self.class.type_for(serializer, serializer_type, transform_options)
|
|
29
60
|
end
|
|
30
61
|
|
|
31
62
|
def id_for(serializer)
|