active_model_serializers 0.10.1 → 0.10.2
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 +4 -4
- data/.rubocop.yml +2 -4
- data/.travis.yml +1 -0
- data/CHANGELOG.md +9 -1
- data/Rakefile +3 -3
- data/active_model_serializers.gemspec +15 -15
- data/docs/general/fields.md +31 -0
- data/docs/general/rendering.md +7 -2
- data/docs/general/serializers.md +32 -0
- data/docs/howto/add_pagination_links.md +2 -3
- data/docs/integrations/ember-and-json-api.md +25 -10
- data/lib/action_controller/serialization.rb +4 -3
- data/lib/active_model/serializer.rb +3 -4
- data/lib/active_model/serializer/array_serializer.rb +8 -5
- data/lib/active_model/serializer/associations.rb +2 -2
- data/lib/active_model/serializer/caching.rb +11 -8
- data/lib/active_model/serializer/error_serializer.rb +11 -7
- data/lib/active_model/serializer/errors_serializer.rb +25 -20
- data/lib/active_model/serializer/lint.rb +134 -130
- data/lib/active_model/serializer/version.rb +1 -1
- data/lib/active_model_serializers/deprecate.rb +1 -1
- data/lib/active_model_serializers/model.rb +1 -1
- data/lib/active_model_serializers/railtie.rb +1 -1
- data/lib/active_model_serializers/register_jsonapi_renderer.rb +37 -35
- data/lib/generators/rails/serializer_generator.rb +3 -3
- data/lib/grape/active_model_serializers.rb +7 -5
- data/test/action_controller/adapter_selector_test.rb +3 -3
- data/test/action_controller/json_api/errors_test.rb +5 -6
- data/test/action_controller/json_api/linked_test.rb +4 -4
- data/test/action_controller/json_api/pagination_test.rb +19 -19
- data/test/action_controller/serialization_test.rb +1 -1
- data/test/active_model_serializers/json_pointer_test.rb +15 -13
- data/test/active_model_serializers/key_transform_test.rb +254 -252
- data/test/active_model_serializers/model_test.rb +6 -4
- data/test/active_model_serializers/register_jsonapi_renderer_test_isolated.rb +2 -2
- data/test/adapter/json/transform_test.rb +14 -14
- data/test/adapter/json_api/errors_test.rb +9 -9
- data/test/adapter/json_api/has_many_test.rb +18 -18
- data/test/adapter/json_api/json_api_test.rb +5 -7
- data/test/adapter/json_api/linked_test.rb +1 -1
- data/test/adapter/json_api/pagination_links_test.rb +6 -6
- data/test/adapter/json_api/resource_meta_test.rb +3 -3
- data/test/adapter/json_api/transform_test.rb +218 -218
- data/test/adapter/json_api/type_test.rb +1 -1
- data/test/adapter/json_test.rb +8 -8
- data/test/adapter/null_test.rb +1 -2
- data/test/adapter/polymorphic_test.rb +5 -5
- data/test/adapter_test.rb +1 -1
- data/test/benchmark/bm_caching.rb +1 -1
- data/test/cache_test.rb +29 -1
- data/test/collection_serializer_test.rb +2 -2
- data/test/fixtures/poro.rb +2 -2
- data/test/grape_test.rb +130 -128
- data/test/lint_test.rb +1 -1
- data/test/logger_test.rb +13 -11
- data/test/serializable_resource_test.rb +12 -16
- data/test/serializers/associations_test.rb +10 -10
- data/test/serializers/attribute_test.rb +1 -1
- data/test/serializers/attributes_test.rb +1 -1
- data/test/serializers/fieldset_test.rb +1 -1
- data/test/serializers/root_test.rb +1 -1
- data/test/serializers/serializer_for_test.rb +3 -1
- data/test/support/isolated_unit.rb +4 -2
- data/test/support/serialization_testing.rb +7 -5
- metadata +3 -3
- data/.rubocop_todo.yml +0 -167
@@ -47,7 +47,7 @@ module ActiveModel
|
|
47
47
|
assert_equal(expected_type, hash.fetch(:data).fetch(:type))
|
48
48
|
end
|
49
49
|
|
50
|
-
def with_jsonapi_resource_type
|
50
|
+
def with_jsonapi_resource_type(inflection)
|
51
51
|
old_inflection = ActiveModelSerializers.config.jsonapi_resource_type
|
52
52
|
ActiveModelSerializers.config.jsonapi_resource_type = inflection
|
53
53
|
yield
|
data/test/adapter/json_test.rb
CHANGED
@@ -32,14 +32,14 @@ module ActiveModelSerializers
|
|
32
32
|
adapter = ActiveModelSerializers::Adapter::Json.new(serializer)
|
33
33
|
|
34
34
|
assert_equal({
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
35
|
+
id: 1,
|
36
|
+
reviews: [
|
37
|
+
{ id: 1, body: 'ZOMG A COMMENT' },
|
38
|
+
{ id: 2, body: 'ZOMG ANOTHER COMMENT' }
|
39
|
+
],
|
40
|
+
writer: { id: 1, name: 'Steve K.' },
|
41
|
+
site: { id: 1, name: 'My Blog!!' }
|
42
|
+
}, adapter.serializable_hash[:post])
|
43
43
|
end
|
44
44
|
end
|
45
45
|
end
|
data/test/adapter/null_test.rb
CHANGED
@@ -4,7 +4,7 @@ module ActiveModelSerializers
|
|
4
4
|
module Adapter
|
5
5
|
class NullTest < ActiveSupport::TestCase
|
6
6
|
def setup
|
7
|
-
profile = Profile.new(
|
7
|
+
profile = Profile.new(name: 'Name 1', description: 'Description 1', comments: 'Comments 1')
|
8
8
|
serializer = ProfileSerializer.new(profile)
|
9
9
|
|
10
10
|
@adapter = Null.new(serializer)
|
@@ -20,4 +20,3 @@ module ActiveModelSerializers
|
|
20
20
|
end
|
21
21
|
end
|
22
22
|
end
|
23
|
-
|
data/test/adapter_test.rb
CHANGED
@@ -51,7 +51,7 @@ module ActiveModelSerializers
|
|
51
51
|
end
|
52
52
|
|
53
53
|
def test_create_adapter_with_override
|
54
|
-
adapter = ActiveModelSerializers::Adapter.create(@serializer,
|
54
|
+
adapter = ActiveModelSerializers::Adapter.create(@serializer, adapter: :json_api)
|
55
55
|
assert_equal ActiveModelSerializers::Adapter::JsonApi, adapter.class
|
56
56
|
end
|
57
57
|
|
data/test/cache_test.rb
CHANGED
@@ -101,7 +101,7 @@ module ActiveModelSerializers
|
|
101
101
|
uncached_author_serializer = AuthorSerializer.new(uncached_author)
|
102
102
|
|
103
103
|
render_object_with_cache(uncached_author)
|
104
|
-
key = "#{uncached_author_serializer.class._cache_key}/#{uncached_author_serializer.object.id}-#{uncached_author_serializer.object.updated_at.strftime(
|
104
|
+
key = "#{uncached_author_serializer.class._cache_key}/#{uncached_author_serializer.object.id}-#{uncached_author_serializer.object.updated_at.strftime('%Y%m%d%H%M%S%9N')}"
|
105
105
|
key = "#{key}/#{adapter.cache_key}"
|
106
106
|
assert_equal(uncached_author_serializer.attributes.to_json, cache_store.fetch(key).to_json)
|
107
107
|
end
|
@@ -321,6 +321,34 @@ module ActiveModelSerializers
|
|
321
321
|
end
|
322
322
|
end
|
323
323
|
|
324
|
+
def test_cache_read_multi_with_fragment_cache_enabled
|
325
|
+
post_serializer = Class.new(ActiveModel::Serializer) do
|
326
|
+
cache except: [:body]
|
327
|
+
end
|
328
|
+
|
329
|
+
serializers = ActiveModel::Serializer::CollectionSerializer.new([@post, @post], serializer: post_serializer)
|
330
|
+
|
331
|
+
Timecop.freeze(Time.current) do
|
332
|
+
# Warming up.
|
333
|
+
options = {}
|
334
|
+
adapter_options = {}
|
335
|
+
adapter_instance = ActiveModelSerializers::Adapter::Attributes.new(serializers, adapter_options)
|
336
|
+
serializers.serializable_hash(adapter_options, options, adapter_instance)
|
337
|
+
|
338
|
+
# Should find something with read_multi now
|
339
|
+
adapter_options = {}
|
340
|
+
serializers.serializable_hash(adapter_options, options, adapter_instance)
|
341
|
+
cached_attributes = adapter_options.fetch(:cached_attributes)
|
342
|
+
|
343
|
+
include_directive = ActiveModelSerializers.default_include_directive
|
344
|
+
manual_cached_attributes = ActiveModel::Serializer.cache_read_multi(serializers, adapter_instance, include_directive)
|
345
|
+
|
346
|
+
refute_equal 0, cached_attributes.size
|
347
|
+
refute_equal 0, manual_cached_attributes.size
|
348
|
+
assert_equal manual_cached_attributes, cached_attributes
|
349
|
+
end
|
350
|
+
end
|
351
|
+
|
324
352
|
def test_serializer_file_path_on_nix
|
325
353
|
path = '/Users/git/emberjs/ember-crm-backend/app/serializers/lead_serializer.rb'
|
326
354
|
caller_line = "#{path}:1:in `<top (required)>'"
|
@@ -11,7 +11,7 @@ module ActiveModel
|
|
11
11
|
@comment = Comment.new
|
12
12
|
@post = Post.new
|
13
13
|
@resource = build_named_collection @comment, @post
|
14
|
-
@serializer = collection_serializer.new(@resource,
|
14
|
+
@serializer = collection_serializer.new(@resource, some: :options)
|
15
15
|
end
|
16
16
|
|
17
17
|
def collection_serializer
|
@@ -44,7 +44,7 @@ module ActiveModel
|
|
44
44
|
end
|
45
45
|
|
46
46
|
def test_serializer_option_not_passed_to_each_serializer
|
47
|
-
serializers = collection_serializer.new([@post],
|
47
|
+
serializers = collection_serializer.new([@post], serializer: PostSerializer).to_a
|
48
48
|
|
49
49
|
refute serializers.first.custom_options.key?(:serializer)
|
50
50
|
end
|
data/test/fixtures/poro.rb
CHANGED
@@ -8,7 +8,7 @@ class Model < ActiveModelSerializers::Model
|
|
8
8
|
# Convenience when not adding @attributes readers and writers
|
9
9
|
def method_missing(meth, *args)
|
10
10
|
if meth.to_s =~ /^(.*)=$/
|
11
|
-
attributes[
|
11
|
+
attributes[Regexp.last_match(1).to_sym] = args[0]
|
12
12
|
elsif attributes.key?(meth)
|
13
13
|
attributes[meth]
|
14
14
|
else
|
@@ -64,7 +64,7 @@ VirtualValue = Class.new(Model)
|
|
64
64
|
Comment = Class.new(Model) do
|
65
65
|
# Uses a custom non-time-based cache key
|
66
66
|
def cache_key
|
67
|
-
"#{self.class.name.downcase}/#{
|
67
|
+
"#{self.class.name.downcase}/#{id}"
|
68
68
|
end
|
69
69
|
end
|
70
70
|
|
data/test/grape_test.rb
CHANGED
@@ -5,172 +5,174 @@ require 'kaminari'
|
|
5
5
|
require 'kaminari/hooks'
|
6
6
|
::Kaminari::Hooks.init
|
7
7
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
8
|
+
module ActiveModelSerializers
|
9
|
+
class GrapeTest < ActiveSupport::TestCase
|
10
|
+
include Rack::Test::Methods
|
11
|
+
module Models
|
12
|
+
def self.model1
|
13
|
+
ARModels::Post.new(id: 1, title: 'Dummy Title', body: 'Lorem Ipsum')
|
14
|
+
end
|
14
15
|
|
15
|
-
|
16
|
-
|
17
|
-
|
16
|
+
def self.model2
|
17
|
+
ARModels::Post.new(id: 2, title: 'Second Dummy Title', body: 'Second Lorem Ipsum')
|
18
|
+
end
|
18
19
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
20
|
+
def self.all
|
21
|
+
@all ||=
|
22
|
+
begin
|
23
|
+
model1.save!
|
24
|
+
model2.save!
|
25
|
+
ARModels::Post.all
|
26
|
+
end
|
27
|
+
end
|
27
28
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
29
|
+
def self.reset_all
|
30
|
+
ARModels::Post.delete_all
|
31
|
+
@all = nil
|
32
|
+
end
|
32
33
|
|
33
|
-
|
34
|
-
|
35
|
-
|
34
|
+
def self.collection_per
|
35
|
+
2
|
36
|
+
end
|
36
37
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
38
|
+
def self.collection
|
39
|
+
@collection ||=
|
40
|
+
begin
|
41
|
+
Kaminari.paginate_array(
|
42
|
+
[
|
43
|
+
Profile.new(id: 1, name: 'Name 1', description: 'Description 1', comments: 'Comments 1'),
|
44
|
+
Profile.new(id: 2, name: 'Name 2', description: 'Description 2', comments: 'Comments 2'),
|
45
|
+
Profile.new(id: 3, name: 'Name 3', description: 'Description 3', comments: 'Comments 3'),
|
46
|
+
Profile.new(id: 4, name: 'Name 4', description: 'Description 4', comments: 'Comments 4'),
|
47
|
+
Profile.new(id: 5, name: 'Name 5', description: 'Description 5', comments: 'Comments 5')
|
47
48
|
]
|
48
|
-
|
49
|
-
|
49
|
+
).page(1).per(collection_per)
|
50
|
+
end
|
51
|
+
end
|
50
52
|
end
|
51
|
-
end
|
52
53
|
|
53
|
-
|
54
|
-
|
55
|
-
|
54
|
+
class GrapeTest < Grape::API
|
55
|
+
format :json
|
56
|
+
include Grape::ActiveModelSerializers
|
56
57
|
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
58
|
+
resources :grape do
|
59
|
+
get '/render' do
|
60
|
+
render Models.model1
|
61
|
+
end
|
61
62
|
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
63
|
+
get '/render_with_json_api' do
|
64
|
+
post = Models.model1
|
65
|
+
render post, meta: { page: 1, total_pages: 2 }, adapter: :json_api
|
66
|
+
end
|
66
67
|
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
68
|
+
get '/render_array_with_json_api' do
|
69
|
+
posts = Models.all
|
70
|
+
render posts, adapter: :json_api
|
71
|
+
end
|
71
72
|
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
73
|
+
get '/render_collection_with_json_api' do
|
74
|
+
posts = Models.collection
|
75
|
+
render posts, adapter: :json_api
|
76
|
+
end
|
76
77
|
|
77
|
-
|
78
|
-
|
79
|
-
|
78
|
+
get '/render_with_implicit_formatter' do
|
79
|
+
Models.model1
|
80
|
+
end
|
80
81
|
|
81
|
-
|
82
|
-
|
83
|
-
|
82
|
+
get '/render_array_with_implicit_formatter' do
|
83
|
+
Models.all
|
84
|
+
end
|
84
85
|
|
85
|
-
|
86
|
-
|
86
|
+
get '/render_collection_with_implicit_formatter' do
|
87
|
+
Models.collection
|
88
|
+
end
|
87
89
|
end
|
88
90
|
end
|
89
|
-
end
|
90
91
|
|
91
|
-
|
92
|
-
|
93
|
-
|
92
|
+
def app
|
93
|
+
Grape::Middleware::Globals.new(GrapeTest.new)
|
94
|
+
end
|
94
95
|
|
95
|
-
|
96
|
-
|
96
|
+
def test_formatter_returns_json
|
97
|
+
get '/grape/render'
|
97
98
|
|
98
|
-
|
99
|
-
|
99
|
+
post = Models.model1
|
100
|
+
serializable_resource = serializable(post)
|
100
101
|
|
101
|
-
|
102
|
-
|
103
|
-
|
102
|
+
assert last_response.ok?
|
103
|
+
assert_equal serializable_resource.to_json, last_response.body
|
104
|
+
end
|
104
105
|
|
105
|
-
|
106
|
-
|
106
|
+
def test_render_helper_passes_through_options_correctly
|
107
|
+
get '/grape/render_with_json_api'
|
107
108
|
|
108
|
-
|
109
|
-
|
109
|
+
post = Models.model1
|
110
|
+
serializable_resource = serializable(post, serializer: ARModels::PostSerializer, adapter: :json_api, meta: { page: 1, total_pages: 2 })
|
110
111
|
|
111
|
-
|
112
|
-
|
113
|
-
|
112
|
+
assert last_response.ok?
|
113
|
+
assert_equal serializable_resource.to_json, last_response.body
|
114
|
+
end
|
114
115
|
|
115
|
-
|
116
|
-
|
116
|
+
def test_formatter_handles_arrays
|
117
|
+
get '/grape/render_array_with_json_api'
|
117
118
|
|
118
|
-
|
119
|
-
|
119
|
+
posts = Models.all
|
120
|
+
serializable_resource = serializable(posts, adapter: :json_api)
|
120
121
|
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
122
|
+
assert last_response.ok?
|
123
|
+
assert_equal serializable_resource.to_json, last_response.body
|
124
|
+
ensure
|
125
|
+
Models.reset_all
|
126
|
+
end
|
126
127
|
|
127
|
-
|
128
|
-
|
129
|
-
|
128
|
+
def test_formatter_handles_collections
|
129
|
+
get '/grape/render_collection_with_json_api'
|
130
|
+
assert last_response.ok?
|
130
131
|
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
132
|
+
representation = JSON.parse(last_response.body)
|
133
|
+
assert representation.include?('data')
|
134
|
+
assert representation['data'].count == Models.collection_per
|
135
|
+
assert representation.include?('links')
|
136
|
+
assert representation['links'].count > 0
|
137
|
+
end
|
138
|
+
|
139
|
+
def test_implicit_formatter
|
140
|
+
post = Models.model1
|
141
|
+
serializable_resource = serializable(post, adapter: :json_api)
|
137
142
|
|
138
|
-
|
139
|
-
|
140
|
-
|
143
|
+
with_adapter :json_api do
|
144
|
+
get '/grape/render_with_implicit_formatter'
|
145
|
+
end
|
141
146
|
|
142
|
-
|
143
|
-
|
147
|
+
assert last_response.ok?
|
148
|
+
assert_equal serializable_resource.to_json, last_response.body
|
144
149
|
end
|
145
150
|
|
146
|
-
|
147
|
-
|
148
|
-
|
151
|
+
def test_implicit_formatter_handles_arrays
|
152
|
+
posts = Models.all
|
153
|
+
serializable_resource = serializable(posts, adapter: :json_api)
|
149
154
|
|
150
|
-
|
151
|
-
|
152
|
-
|
155
|
+
with_adapter :json_api do
|
156
|
+
get '/grape/render_array_with_implicit_formatter'
|
157
|
+
end
|
153
158
|
|
154
|
-
|
155
|
-
|
159
|
+
assert last_response.ok?
|
160
|
+
assert_equal serializable_resource.to_json, last_response.body
|
161
|
+
ensure
|
162
|
+
Models.reset_all
|
156
163
|
end
|
157
164
|
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
end
|
165
|
+
def test_implicit_formatter_handles_collections
|
166
|
+
with_adapter :json_api do
|
167
|
+
get '/grape/render_collection_with_implicit_formatter'
|
168
|
+
end
|
163
169
|
|
164
|
-
|
165
|
-
|
166
|
-
|
170
|
+
representation = JSON.parse(last_response.body)
|
171
|
+
assert last_response.ok?
|
172
|
+
assert representation.include?('data')
|
173
|
+
assert representation['data'].count == Models.collection_per
|
174
|
+
assert representation.include?('links')
|
175
|
+
assert representation['links'].count > 0
|
167
176
|
end
|
168
|
-
|
169
|
-
representation = JSON.parse(last_response.body)
|
170
|
-
assert last_response.ok?
|
171
|
-
assert representation.include?('data')
|
172
|
-
assert representation['data'].count == Models.collection_per
|
173
|
-
assert representation.include?('links')
|
174
|
-
assert representation['links'].count > 0
|
175
177
|
end
|
176
178
|
end
|