active_model_serializers 0.10.0 → 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 +39 -2
- data/Gemfile +1 -1
- data/README.md +21 -24
- data/Rakefile +3 -3
- data/active_model_serializers.gemspec +19 -23
- data/docs/general/adapters.md +4 -2
- data/docs/general/configuration_options.md +6 -1
- data/docs/general/deserialization.md +1 -1
- data/docs/general/fields.md +31 -0
- data/docs/general/rendering.md +7 -2
- data/docs/general/serializers.md +62 -3
- data/docs/howto/add_pagination_links.md +2 -3
- data/docs/integrations/ember-and-json-api.md +25 -10
- data/docs/jsonapi/schema.md +1 -1
- data/lib/action_controller/serialization.rb +4 -3
- data/lib/active_model/serializer/adapter/base.rb +2 -0
- data/lib/active_model/serializer/array_serializer.rb +8 -5
- data/lib/active_model/serializer/associations.rb +6 -7
- data/lib/active_model/serializer/belongs_to_reflection.rb +0 -3
- data/lib/active_model/serializer/caching.rb +67 -112
- data/lib/active_model/serializer/collection_serializer.rb +30 -10
- data/lib/active_model/serializer/configuration.rb +1 -0
- 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/has_many_reflection.rb +0 -3
- data/lib/active_model/serializer/has_one_reflection.rb +0 -3
- data/lib/active_model/serializer/lint.rb +134 -130
- data/lib/active_model/serializer/reflection.rb +3 -3
- data/lib/active_model/serializer/version.rb +1 -1
- data/lib/active_model/serializer.rb +57 -15
- data/lib/active_model_serializers/adapter/attributes.rb +2 -67
- data/lib/active_model_serializers/adapter/base.rb +38 -38
- data/lib/active_model_serializers/adapter/json_api/link.rb +1 -1
- data/lib/active_model_serializers/adapter/json_api/pagination_links.rb +8 -1
- data/lib/active_model_serializers/adapter/json_api.rb +36 -28
- data/lib/active_model_serializers/adapter.rb +6 -0
- data/lib/active_model_serializers/deprecate.rb +1 -2
- data/lib/active_model_serializers/deserialization.rb +2 -0
- data/lib/active_model_serializers/model.rb +3 -1
- data/lib/active_model_serializers/railtie.rb +3 -1
- data/lib/active_model_serializers/register_jsonapi_renderer.rb +44 -31
- data/lib/active_model_serializers/serialization_context.rb +10 -3
- data/lib/active_model_serializers.rb +6 -0
- data/lib/generators/rails/serializer_generator.rb +3 -3
- data/lib/grape/active_model_serializers.rb +7 -5
- data/lib/grape/formatters/active_model_serializers.rb +19 -2
- data/lib/grape/helpers/active_model_serializers.rb +1 -0
- data/test/action_controller/adapter_selector_test.rb +4 -4
- data/test/action_controller/explicit_serializer_test.rb +5 -4
- data/test/action_controller/json/include_test.rb +106 -27
- data/test/action_controller/json_api/errors_test.rb +6 -7
- data/test/action_controller/json_api/linked_test.rb +29 -24
- data/test/action_controller/json_api/pagination_test.rb +19 -19
- data/test/action_controller/serialization_test.rb +10 -7
- 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 +143 -0
- data/test/active_model_serializers/serialization_context_test_isolated.rb +23 -10
- data/test/adapter/json/collection_test.rb +14 -0
- data/test/adapter/json/transform_test.rb +14 -14
- data/test/adapter/json_api/collection_test.rb +4 -3
- data/test/adapter/json_api/errors_test.rb +17 -19
- 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 +9 -6
- data/test/adapter/json_api/links_test.rb +3 -1
- data/test/adapter/json_api/pagination_links_test.rb +19 -7
- data/test/adapter/json_api/relationships_test.rb +9 -4
- data/test/adapter/json_api/resource_identifier_test.rb +7 -2
- data/test/adapter/json_api/resource_meta_test.rb +3 -3
- data/test/adapter/json_api/transform_test.rb +251 -250
- data/test/adapter/json_api/type_test.rb +1 -1
- data/test/adapter/json_test.rb +8 -7
- 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/app.rb +1 -1
- data/test/benchmark/bm_caching.rb +15 -15
- data/test/benchmark/bm_transform.rb +16 -5
- data/test/benchmark/controllers.rb +16 -17
- data/test/benchmark/fixtures.rb +72 -72
- data/test/cache_test.rb +101 -45
- data/test/collection_serializer_test.rb +2 -2
- data/test/fixtures/poro.rb +8 -7
- data/test/grape_test.rb +152 -56
- data/test/lint_test.rb +1 -1
- data/test/logger_test.rb +13 -11
- data/test/serializable_resource_test.rb +18 -22
- 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/meta_test.rb +12 -6
- data/test/serializers/root_test.rb +1 -1
- data/test/serializers/serializer_for_test.rb +3 -1
- data/test/support/isolated_unit.rb +5 -2
- data/test/support/rails5_shims.rb +8 -2
- data/test/support/rails_app.rb +0 -9
- data/test/support/serialization_testing.rb +7 -5
- metadata +54 -24
- data/.rubocop_todo.yml +0 -167
- data/lib/active_model/serializer/include_tree.rb +0 -111
- 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/cache_test.rb
CHANGED
@@ -101,14 +101,14 @@ 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(
|
105
|
-
key = "#{key}/#{adapter.
|
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
|
+
key = "#{key}/#{adapter.cache_key}"
|
106
106
|
assert_equal(uncached_author_serializer.attributes.to_json, cache_store.fetch(key).to_json)
|
107
107
|
end
|
108
108
|
|
109
109
|
def test_default_cache_key_fallback
|
110
110
|
render_object_with_cache(@comment)
|
111
|
-
key = "#{@comment.cache_key}/#{adapter.
|
111
|
+
key = "#{@comment.cache_key}/#{adapter.cache_key}"
|
112
112
|
assert_equal(@comment_serializer.attributes.to_json, cache_store.fetch(key).to_json)
|
113
113
|
end
|
114
114
|
|
@@ -117,7 +117,7 @@ module ActiveModelSerializers
|
|
117
117
|
e = assert_raises ActiveModel::Serializer::UndefinedCacheKey do
|
118
118
|
render_object_with_cache(article)
|
119
119
|
end
|
120
|
-
assert_match(/ActiveModelSerializers::CacheTest::Article must define #cache_key, or the 'key:' option must be passed into '
|
120
|
+
assert_match(/ActiveModelSerializers::CacheTest::Article must define #cache_key, or the 'key:' option must be passed into 'ActiveModelSerializers::CacheTest::ArticleSerializer.cache'/, e.message)
|
121
121
|
end
|
122
122
|
|
123
123
|
def test_cache_options_definition
|
@@ -127,7 +127,7 @@ module ActiveModelSerializers
|
|
127
127
|
end
|
128
128
|
|
129
129
|
def test_fragment_cache_definition
|
130
|
-
assert_equal([:name], @role_serializer.class._cache_only)
|
130
|
+
assert_equal([:name, :slug], @role_serializer.class._cache_only)
|
131
131
|
assert_equal([:content], @bio_serializer.class._cache_except)
|
132
132
|
end
|
133
133
|
|
@@ -139,9 +139,9 @@ module ActiveModelSerializers
|
|
139
139
|
Timecop.freeze(Time.current) do
|
140
140
|
render_object_with_cache(@post)
|
141
141
|
|
142
|
-
key = "#{@post.cache_key}/#{adapter.
|
142
|
+
key = "#{@post.cache_key}/#{adapter.cache_key}"
|
143
143
|
assert_equal(@post_serializer.attributes, cache_store.fetch(key))
|
144
|
-
key = "#{@comment.cache_key}/#{adapter.
|
144
|
+
key = "#{@comment.cache_key}/#{adapter.cache_key}"
|
145
145
|
assert_equal(@comment_serializer.attributes, cache_store.fetch(key))
|
146
146
|
end
|
147
147
|
end
|
@@ -152,9 +152,9 @@ module ActiveModelSerializers
|
|
152
152
|
render_object_with_cache(@post)
|
153
153
|
|
154
154
|
# Check if it cached the objects separately
|
155
|
-
key = "#{@post.cache_key}/#{adapter.
|
155
|
+
key = "#{@post.cache_key}/#{adapter.cache_key}"
|
156
156
|
assert_equal(@post_serializer.attributes, cache_store.fetch(key))
|
157
|
-
key = "#{@comment.cache_key}/#{adapter.
|
157
|
+
key = "#{@comment.cache_key}/#{adapter.cache_key}"
|
158
158
|
assert_equal(@comment_serializer.attributes, cache_store.fetch(key))
|
159
159
|
|
160
160
|
# Simulating update on comments relationship with Post
|
@@ -166,9 +166,9 @@ module ActiveModelSerializers
|
|
166
166
|
render_object_with_cache(@post)
|
167
167
|
|
168
168
|
# Check if the the new comment was cached
|
169
|
-
key = "#{new_comment.cache_key}/#{adapter.
|
169
|
+
key = "#{new_comment.cache_key}/#{adapter.cache_key}"
|
170
170
|
assert_equal(new_comment_serializer.attributes, cache_store.fetch(key))
|
171
|
-
key = "#{@post.cache_key}/#{adapter.
|
171
|
+
key = "#{@post.cache_key}/#{adapter.cache_key}"
|
172
172
|
assert_equal(@post_serializer.attributes, cache_store.fetch(key))
|
173
173
|
end
|
174
174
|
end
|
@@ -178,14 +178,14 @@ module ActiveModelSerializers
|
|
178
178
|
id: @location.id,
|
179
179
|
lat: @location.lat,
|
180
180
|
lng: @location.lng,
|
181
|
-
|
181
|
+
address: 'Nowhere'
|
182
182
|
}
|
183
183
|
|
184
184
|
hash = render_object_with_cache(@location)
|
185
185
|
|
186
186
|
assert_equal(hash, expected_result)
|
187
|
-
key = "#{@location.cache_key}/#{adapter.
|
188
|
-
assert_equal({
|
187
|
+
key = "#{@location.cache_key}/#{adapter.cache_key}"
|
188
|
+
assert_equal({ address: 'Nowhere' }, cache_store.fetch(key))
|
189
189
|
end
|
190
190
|
|
191
191
|
def test_fragment_cache_with_inheritance
|
@@ -204,7 +204,7 @@ module ActiveModelSerializers
|
|
204
204
|
|
205
205
|
# Based on original failing test by @kevintyll
|
206
206
|
# rubocop:disable Metrics/AbcSize
|
207
|
-
def
|
207
|
+
def test_a_serializer_rendered_by_two_adapter_returns_differently_fetch_attributes
|
208
208
|
Object.const_set(:Alert, Class.new(ActiveModelSerializers::Model) do
|
209
209
|
attr_accessor :id, :status, :resource, :started_at, :ended_at, :updated_at, :created_at
|
210
210
|
end)
|
@@ -225,7 +225,7 @@ module ActiveModelSerializers
|
|
225
225
|
created_at: Time.new(2016, 3, 31, 21, 37, 35, 0)
|
226
226
|
)
|
227
227
|
|
228
|
-
|
228
|
+
expected_fetch_attributes = {
|
229
229
|
id: 1,
|
230
230
|
status: 'fail',
|
231
231
|
resource: 'resource-1',
|
@@ -250,7 +250,7 @@ module ActiveModelSerializers
|
|
250
250
|
# Assert attributes are serialized correctly
|
251
251
|
serializable_alert = serializable(alert, serializer: AlertSerializer, adapter: :attributes)
|
252
252
|
attributes_serialization = serializable_alert.as_json
|
253
|
-
assert_equal
|
253
|
+
assert_equal expected_fetch_attributes, alert.attributes
|
254
254
|
assert_equal alert.attributes, attributes_serialization
|
255
255
|
attributes_cache_key = serializable_alert.adapter.serializer.cache_key(serializable_alert.adapter)
|
256
256
|
assert_equal attributes_serialization, cache_store.fetch(attributes_cache_key)
|
@@ -276,7 +276,7 @@ module ActiveModelSerializers
|
|
276
276
|
|
277
277
|
def test_uses_file_digest_in_cache_key
|
278
278
|
render_object_with_cache(@blog)
|
279
|
-
key = "#{@blog.cache_key}/#{adapter.
|
279
|
+
key = "#{@blog.cache_key}/#{adapter.cache_key}/#{::Model::FILE_DIGEST}"
|
280
280
|
assert_equal(@blog_serializer.attributes, cache_store.fetch(key))
|
281
281
|
end
|
282
282
|
|
@@ -286,33 +286,66 @@ module ActiveModelSerializers
|
|
286
286
|
|
287
287
|
def test_object_cache_keys
|
288
288
|
serializable = ActiveModelSerializers::SerializableResource.new([@comment, @comment])
|
289
|
-
|
289
|
+
include_directive = JSONAPI::IncludeDirective.new('*', allow_wildcard: true)
|
290
290
|
|
291
|
-
actual = ActiveModel::Serializer.object_cache_keys(serializable.adapter.serializer, serializable.adapter,
|
291
|
+
actual = ActiveModel::Serializer.object_cache_keys(serializable.adapter.serializer, serializable.adapter, include_directive)
|
292
292
|
|
293
293
|
assert_equal 3, actual.size
|
294
|
-
assert actual.any? { |key| key == "comment/1/#{serializable.adapter.
|
294
|
+
assert actual.any? { |key| key == "comment/1/#{serializable.adapter.cache_key}" }
|
295
295
|
assert actual.any? { |key| key =~ %r{post/post-\d+} }
|
296
296
|
assert actual.any? { |key| key =~ %r{author/author-\d+} }
|
297
297
|
end
|
298
298
|
|
299
|
-
def
|
300
|
-
|
299
|
+
def test_fetch_attributes_from_cache
|
300
|
+
serializers = ActiveModel::Serializer::CollectionSerializer.new([@comment, @comment])
|
301
301
|
|
302
302
|
Timecop.freeze(Time.current) do
|
303
303
|
render_object_with_cache(@comment)
|
304
304
|
|
305
|
-
|
306
|
-
|
307
|
-
|
305
|
+
options = {}
|
306
|
+
adapter_options = {}
|
307
|
+
adapter_instance = ActiveModelSerializers::Adapter::Attributes.new(serializers, adapter_options)
|
308
|
+
serializers.serializable_hash(adapter_options, options, adapter_instance)
|
309
|
+
cached_attributes = adapter_options.fetch(:cached_attributes)
|
308
310
|
|
309
|
-
|
310
|
-
|
311
|
+
include_directive = ActiveModelSerializers.default_include_directive
|
312
|
+
manual_cached_attributes = ActiveModel::Serializer.cache_read_multi(serializers, adapter_instance, include_directive)
|
313
|
+
assert_equal manual_cached_attributes, cached_attributes
|
314
|
+
|
315
|
+
assert_equal cached_attributes["#{@comment.cache_key}/#{adapter_instance.cache_key}"], Comment.new(id: 1, body: 'ZOMG A COMMENT').attributes
|
316
|
+
assert_equal cached_attributes["#{@comment.post.cache_key}/#{adapter_instance.cache_key}"], Post.new(id: 'post', title: 'New Post', body: 'Body').attributes
|
311
317
|
|
312
318
|
writer = @comment.post.blog.writer
|
313
319
|
writer_cache_key = writer.cache_key
|
320
|
+
assert_equal cached_attributes["#{writer_cache_key}/#{adapter_instance.cache_key}"], Author.new(id: 'author', name: 'Joao M. D. Moura').attributes
|
321
|
+
end
|
322
|
+
end
|
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
|
314
328
|
|
315
|
-
|
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
|
316
349
|
end
|
317
350
|
end
|
318
351
|
|
@@ -429,25 +462,53 @@ module ActiveModelSerializers
|
|
429
462
|
end
|
430
463
|
|
431
464
|
def test_fragment_fetch_with_virtual_attributes
|
432
|
-
|
433
|
-
|
434
|
-
|
435
|
-
|
436
|
-
|
465
|
+
author = Author.new(name: 'Joao M. D. Moura')
|
466
|
+
role = Role.new(name: 'Great Author', description: nil)
|
467
|
+
role.author = [author]
|
468
|
+
role_serializer = RoleSerializer.new(role)
|
469
|
+
adapter_instance = ActiveModelSerializers::Adapter.configured_adapter.new(role_serializer)
|
470
|
+
expected_result = {
|
471
|
+
id: role.id,
|
472
|
+
description: role.description,
|
473
|
+
slug: "#{role.name}-#{role.id}",
|
474
|
+
name: role.name
|
475
|
+
}
|
476
|
+
cache_store.clear
|
437
477
|
|
478
|
+
role_hash = role_serializer.fetch_attributes_fragment(adapter_instance)
|
479
|
+
assert_equal(role_hash, expected_result)
|
480
|
+
|
481
|
+
role.attributes[:id] = 'this has been updated'
|
482
|
+
role.name = 'this was cached'
|
483
|
+
|
484
|
+
role_hash = role_serializer.fetch_attributes_fragment(adapter_instance)
|
485
|
+
assert_equal(expected_result.merge(id: role.id), role_hash)
|
486
|
+
end
|
487
|
+
|
488
|
+
def test_fragment_fetch_with_except
|
489
|
+
adapter_instance = ActiveModelSerializers::Adapter.configured_adapter.new(@bio_serializer)
|
438
490
|
expected_result = {
|
439
|
-
id: @
|
440
|
-
|
441
|
-
|
442
|
-
name: @role.name
|
491
|
+
id: @bio.id,
|
492
|
+
rating: nil,
|
493
|
+
content: @bio.content
|
443
494
|
}
|
444
|
-
|
495
|
+
cache_store.clear
|
496
|
+
|
497
|
+
bio_hash = @bio_serializer.fetch_attributes_fragment(adapter_instance)
|
498
|
+
assert_equal(expected_result, bio_hash)
|
499
|
+
|
500
|
+
@bio.content = 'this has been updated'
|
501
|
+
@bio.rating = 'this was cached'
|
502
|
+
|
503
|
+
bio_hash = @bio_serializer.fetch_attributes_fragment(adapter_instance)
|
504
|
+
assert_equal(expected_result.merge(content: @bio.content), bio_hash)
|
445
505
|
end
|
446
506
|
|
447
507
|
def test_fragment_fetch_with_namespaced_object
|
448
508
|
@spam = Spam::UnrelatedLink.new(id: 'spam-id-1')
|
449
509
|
@spam_serializer = Spam::UnrelatedLinkSerializer.new(@spam)
|
450
|
-
|
510
|
+
adapter_instance = ActiveModelSerializers::Adapter.configured_adapter.new(@spam_serializer)
|
511
|
+
@spam_hash = @spam_serializer.fetch_attributes_fragment(adapter_instance)
|
451
512
|
expected_result = {
|
452
513
|
id: @spam.id
|
453
514
|
}
|
@@ -476,10 +537,5 @@ module ActiveModelSerializers
|
|
476
537
|
def adapter
|
477
538
|
@serializable_resource.adapter
|
478
539
|
end
|
479
|
-
|
480
|
-
def cached_serialization(serializer)
|
481
|
-
cache_key = serializer.cache_key(adapter)
|
482
|
-
cache_store.fetch(cache_key)
|
483
|
-
end
|
484
540
|
end
|
485
541
|
end
|
@@ -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
|
|
@@ -136,10 +136,11 @@ AuthorSerializer = Class.new(ActiveModel::Serializer) do
|
|
136
136
|
end
|
137
137
|
|
138
138
|
RoleSerializer = Class.new(ActiveModel::Serializer) do
|
139
|
-
cache only: [:name], skip_digest: true
|
140
|
-
attributes :id, :name, :description
|
139
|
+
cache only: [:name, :slug], skip_digest: true
|
140
|
+
attributes :id, :name, :description
|
141
|
+
attribute :friendly_id, key: :slug
|
141
142
|
|
142
|
-
def
|
143
|
+
def friendly_id
|
143
144
|
"#{object.name}-#{object.id}"
|
144
145
|
end
|
145
146
|
|
@@ -153,10 +154,10 @@ LikeSerializer = Class.new(ActiveModel::Serializer) do
|
|
153
154
|
end
|
154
155
|
|
155
156
|
LocationSerializer = Class.new(ActiveModel::Serializer) do
|
156
|
-
cache only: [:
|
157
|
+
cache only: [:address], skip_digest: true
|
157
158
|
attributes :id, :lat, :lng
|
158
159
|
|
159
|
-
belongs_to :place
|
160
|
+
belongs_to :place, key: :address
|
160
161
|
|
161
162
|
def place
|
162
163
|
'Nowhere'
|
data/test/grape_test.rb
CHANGED
@@ -1,82 +1,178 @@
|
|
1
1
|
require 'test_helper'
|
2
2
|
require 'grape'
|
3
3
|
require 'grape/active_model_serializers'
|
4
|
+
require 'kaminari'
|
5
|
+
require 'kaminari/hooks'
|
6
|
+
::Kaminari::Hooks.init
|
7
|
+
|
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
|
4
15
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
16
|
+
def self.model2
|
17
|
+
ARModels::Post.new(id: 2, title: 'Second Dummy Title', body: 'Second Lorem Ipsum')
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.all
|
21
|
+
@all ||=
|
22
|
+
begin
|
23
|
+
model1.save!
|
24
|
+
model2.save!
|
25
|
+
ARModels::Post.all
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.reset_all
|
30
|
+
ARModels::Post.delete_all
|
31
|
+
@all = nil
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.collection_per
|
35
|
+
2
|
36
|
+
end
|
11
37
|
|
12
|
-
|
13
|
-
|
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')
|
48
|
+
]
|
49
|
+
).page(1).per(collection_per)
|
50
|
+
end
|
51
|
+
end
|
14
52
|
end
|
15
53
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
54
|
+
class GrapeTest < Grape::API
|
55
|
+
format :json
|
56
|
+
include Grape::ActiveModelSerializers
|
57
|
+
|
58
|
+
resources :grape do
|
59
|
+
get '/render' do
|
60
|
+
render Models.model1
|
22
61
|
end
|
23
|
-
end
|
24
|
-
end
|
25
62
|
|
26
|
-
|
27
|
-
|
28
|
-
|
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
|
29
67
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
68
|
+
get '/render_array_with_json_api' do
|
69
|
+
posts = Models.all
|
70
|
+
render posts, adapter: :json_api
|
71
|
+
end
|
34
72
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
73
|
+
get '/render_collection_with_json_api' do
|
74
|
+
posts = Models.collection
|
75
|
+
render posts, adapter: :json_api
|
76
|
+
end
|
39
77
|
|
40
|
-
|
41
|
-
|
42
|
-
|
78
|
+
get '/render_with_implicit_formatter' do
|
79
|
+
Models.model1
|
80
|
+
end
|
81
|
+
|
82
|
+
get '/render_array_with_implicit_formatter' do
|
83
|
+
Models.all
|
84
|
+
end
|
85
|
+
|
86
|
+
get '/render_collection_with_implicit_formatter' do
|
87
|
+
Models.collection
|
88
|
+
end
|
43
89
|
end
|
44
90
|
end
|
45
|
-
end
|
46
91
|
|
47
|
-
|
48
|
-
|
49
|
-
|
92
|
+
def app
|
93
|
+
Grape::Middleware::Globals.new(GrapeTest.new)
|
94
|
+
end
|
50
95
|
|
51
|
-
|
52
|
-
|
96
|
+
def test_formatter_returns_json
|
97
|
+
get '/grape/render'
|
53
98
|
|
54
|
-
|
55
|
-
|
99
|
+
post = Models.model1
|
100
|
+
serializable_resource = serializable(post)
|
56
101
|
|
57
|
-
|
58
|
-
|
59
|
-
|
102
|
+
assert last_response.ok?
|
103
|
+
assert_equal serializable_resource.to_json, last_response.body
|
104
|
+
end
|
60
105
|
|
61
|
-
|
62
|
-
|
106
|
+
def test_render_helper_passes_through_options_correctly
|
107
|
+
get '/grape/render_with_json_api'
|
63
108
|
|
64
|
-
|
65
|
-
|
109
|
+
post = Models.model1
|
110
|
+
serializable_resource = serializable(post, serializer: ARModels::PostSerializer, adapter: :json_api, meta: { page: 1, total_pages: 2 })
|
66
111
|
|
67
|
-
|
68
|
-
|
69
|
-
|
112
|
+
assert last_response.ok?
|
113
|
+
assert_equal serializable_resource.to_json, last_response.body
|
114
|
+
end
|
115
|
+
|
116
|
+
def test_formatter_handles_arrays
|
117
|
+
get '/grape/render_array_with_json_api'
|
118
|
+
|
119
|
+
posts = Models.all
|
120
|
+
serializable_resource = serializable(posts, adapter: :json_api)
|
121
|
+
|
122
|
+
assert last_response.ok?
|
123
|
+
assert_equal serializable_resource.to_json, last_response.body
|
124
|
+
ensure
|
125
|
+
Models.reset_all
|
126
|
+
end
|
127
|
+
|
128
|
+
def test_formatter_handles_collections
|
129
|
+
get '/grape/render_collection_with_json_api'
|
130
|
+
assert last_response.ok?
|
131
|
+
|
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)
|
142
|
+
|
143
|
+
with_adapter :json_api do
|
144
|
+
get '/grape/render_with_implicit_formatter'
|
145
|
+
end
|
146
|
+
|
147
|
+
assert last_response.ok?
|
148
|
+
assert_equal serializable_resource.to_json, last_response.body
|
149
|
+
end
|
70
150
|
|
71
|
-
|
72
|
-
|
151
|
+
def test_implicit_formatter_handles_arrays
|
152
|
+
posts = Models.all
|
153
|
+
serializable_resource = serializable(posts, adapter: :json_api)
|
73
154
|
|
74
|
-
|
75
|
-
|
155
|
+
with_adapter :json_api do
|
156
|
+
get '/grape/render_array_with_implicit_formatter'
|
157
|
+
end
|
158
|
+
|
159
|
+
assert last_response.ok?
|
160
|
+
assert_equal serializable_resource.to_json, last_response.body
|
161
|
+
ensure
|
162
|
+
Models.reset_all
|
163
|
+
end
|
76
164
|
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
165
|
+
def test_implicit_formatter_handles_collections
|
166
|
+
with_adapter :json_api do
|
167
|
+
get '/grape/render_collection_with_implicit_formatter'
|
168
|
+
end
|
169
|
+
|
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
|
176
|
+
end
|
81
177
|
end
|
82
178
|
end
|
data/test/lint_test.rb
CHANGED
data/test/logger_test.rb
CHANGED
@@ -1,18 +1,20 @@
|
|
1
1
|
require 'test_helper'
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
3
|
+
module ActiveModelSerializers
|
4
|
+
class LoggerTest < ActiveSupport::TestCase
|
5
|
+
def test_logger_is_set_to_action_controller_logger_when_initializer_runs
|
6
|
+
assert_equal $action_controller_logger, ActionController::Base.logger # rubocop:disable Style/GlobalVars
|
7
|
+
end
|
7
8
|
|
8
|
-
|
9
|
-
|
10
|
-
|
9
|
+
def test_logger_can_be_set
|
10
|
+
original_logger = ActiveModelSerializers.logger
|
11
|
+
logger = Logger.new(STDOUT)
|
11
12
|
|
12
|
-
|
13
|
+
ActiveModelSerializers.logger = logger
|
13
14
|
|
14
|
-
|
15
|
-
|
16
|
-
|
15
|
+
assert_equal ActiveModelSerializers.logger, logger
|
16
|
+
ensure
|
17
|
+
ActiveModelSerializers.logger = original_logger
|
18
|
+
end
|
17
19
|
end
|
18
20
|
end
|