active_model_serializers 0.9.7 → 0.9.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 +41 -1
- data/README.md +1 -1
- data/lib/action_controller/serialization.rb +18 -1
- data/lib/action_controller/serialization_test_case.rb +3 -0
- data/lib/active_model/array_serializer.rb +2 -0
- data/lib/active_model/default_serializer.rb +2 -0
- data/lib/active_model/serializable/utils.rb +2 -0
- data/lib/active_model/serializable.rb +3 -1
- data/lib/active_model/serializer/association/has_many.rb +2 -0
- data/lib/active_model/serializer/association/has_one.rb +2 -0
- data/lib/active_model/serializer/association.rb +3 -3
- data/lib/active_model/serializer/config.rb +2 -0
- data/lib/active_model/serializer/generators/resource_override.rb +2 -0
- data/lib/active_model/serializer/generators/serializer/scaffold_controller_generator.rb +2 -0
- data/lib/active_model/serializer/generators/serializer/serializer_generator.rb +2 -0
- data/lib/active_model/serializer/railtie.rb +2 -0
- data/lib/active_model/serializer/version.rb +3 -1
- data/lib/active_model/serializer.rb +36 -13
- data/lib/active_model/serializer_support.rb +2 -0
- data/lib/active_model_serializers.rb +14 -2
- data/test/benchmark/tmp/miniprofiler/mp_timers_6eqewtfgrhitvq5gqm25 +0 -0
- data/test/benchmark/tmp/miniprofiler/{mp_timers_6b9d32ftlk8v5xy2op05 → mp_timers_8083sx03hu72pxz1a4d0} +0 -0
- data/test/benchmark/tmp/miniprofiler/{mp_timers_3f0bdfx4nib4hxfb5lmq → mp_timers_fyz2gsml4z0ph9kpoy1c} +0 -0
- data/test/benchmark/tmp/miniprofiler/{mp_timers_m78k2w11sd7ba5oh40rw → mp_timers_hjry5rc32imd42oxoi48} +0 -0
- data/test/benchmark/tmp/miniprofiler/{mp_timers_7nlok5ykeley83h8bine → mp_timers_m8fpoz2cvt3g9agz0bs3} +0 -0
- data/test/benchmark/tmp/miniprofiler/{mp_timers_uc1b3hwqrd4q512gy6c9 → mp_timers_p92m2drnj1i568u3sta0} +0 -0
- data/test/benchmark/tmp/miniprofiler/mp_timers_qg52tpca3uesdfguee9i +0 -0
- data/test/benchmark/tmp/miniprofiler/{mp_timers_c3a27vo6uvfijeh105nt → mp_timers_s15t1a6mvxe0z7vjv790} +0 -0
- data/test/benchmark/tmp/miniprofiler/{mp_timers_54wkvaidi0avdc8yawyt → mp_timers_x8kal3d17nfds6vp4kcj} +0 -0
- data/test/benchmark/tmp/miniprofiler/mp_views_127.0.0.1 +0 -0
- data/test/fixtures/poro.rb +35 -3
- data/test/integration/action_controller/serialization_test.rb +13 -13
- data/test/integration/action_controller/serialization_test_case_test.rb +1 -1
- data/test/integration/generators/scaffold_controller_generator_test.rb +20 -20
- data/test/test_app.rb +4 -0
- data/test/test_helper.rb +7 -0
- data/test/unit/active_model/array_serializer/serialization_test.rb +23 -0
- data/test/unit/active_model/default_serializer_test.rb +1 -1
- data/test/unit/active_model/serializer/has_many_polymorphic_test.rb +1 -1
- data/test/unit/active_model/serializer/has_one_polymorphic_test.rb +1 -1
- data/test/unit/active_model/serializer/url_helpers_test.rb +1 -0
- metadata +24 -70
- data/lib/bulk_cache_fetcher.rb +0 -105
- data/test/action_controller/http_cache_test.rb +0 -56
- data/test/action_controller/regression_test.rb +0 -35
- data/test/benchmark/bm_rails_cache.rb +0 -141
- data/test/benchmark/tmp/miniprofiler/mp_timers_16x1i2wkkt8b8zybbfbx +0 -0
- data/test/benchmark/tmp/miniprofiler/mp_timers_3aa299ezxdqvog6sfjzr +0 -0
- data/test/benchmark/tmp/miniprofiler/mp_timers_b36ymkc1vgu5fy9fvm9k +0 -0
- data/test/benchmark/tmp/miniprofiler/mp_timers_eqcbrj14r4c341abi3h6 +0 -0
- data/test/benchmark/tmp/miniprofiler/mp_timers_hqodkd691tbr7sbfdiez +0 -0
- data/test/benchmark/tmp/miniprofiler/mp_timers_j7y5frtod7cw4qc4cear +0 -0
- data/test/benchmark/tmp/miniprofiler/mp_timers_jpxzfgo92l24t7wzt8g1 +0 -0
- data/test/benchmark/tmp/miniprofiler/mp_timers_mkvat4ehphrje9n2hu3t +0 -0
- data/test/benchmark/tmp/miniprofiler/mp_timers_nd3ymt54l1ga22i2brn8 +0 -0
- data/test/benchmark/tmp/miniprofiler/mp_timers_o2dk1yhw6ez9jzxf6p0a +0 -0
- data/test/benchmark/tmp/miniprofiler/mp_timers_p76i310zb4y12iqm5o0n +0 -0
- data/test/benchmark/tmp/miniprofiler/mp_timers_pi3hvrrkfxnxl300wvah +0 -0
- data/test/benchmark/tmp/miniprofiler/mp_timers_q4w5d86flb4u9tsadqvw +0 -0
- data/test/benchmark/tmp/miniprofiler/mp_timers_sfa5nundogo63o056n5y +0 -0
- data/test/benchmark/tmp/miniprofiler/mp_timers_tkjlmqeauf5gur2u5nob +0 -0
- data/test/benchmark/tmp/miniprofiler/mp_timers_tngbj11ilv2i75rqn2d2 +0 -0
- data/test/benchmark/tmp/miniprofiler/mp_timers_u4haqgvgybvc1sb5nihw +0 -0
- data/test/benchmark/tmp/miniprofiler/mp_timers_uwholuf0iix2vvbo2l3c +0 -0
- data/test/benchmark/tmp/miniprofiler/mp_timers_waye238ygft3p4xvppc4 +0 -0
- data/test/benchmark/tmp/miniprofiler/mp_timers_ydwo7p117loo2ky40lk3 +0 -0
- data/test/benchmark/tmp/miniprofiler/mp_timers_zhgmyfizfa8slppitgua +0 -0
data/test/test_app.rb
CHANGED
data/test/test_helper.rb
CHANGED
@@ -2,6 +2,13 @@ require 'bundler/setup'
|
|
2
2
|
require 'minitest/autorun'
|
3
3
|
require 'active_model_serializers'
|
4
4
|
require 'fixtures/poro'
|
5
|
+
begin
|
6
|
+
require 'rails-controller-testing'
|
7
|
+
Rails::Controller::Testing.install
|
8
|
+
rescue LoadError
|
9
|
+
false # Rails 5 < backward compatibility
|
10
|
+
end
|
11
|
+
|
5
12
|
|
6
13
|
# Ensure backward compatibility with Minitest 4
|
7
14
|
Minitest::Test = MiniTest::Unit::TestCase unless defined?(Minitest::Test)
|
@@ -49,6 +49,29 @@ module ActiveModel
|
|
49
49
|
def object.serializer_class; CustomSerializer; end
|
50
50
|
|
51
51
|
assert_equal CustomSerializer, Serializer.serializer_for(object)
|
52
|
+
assert_nil Serializer.serializer_for('Custom')
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
class ModelSerializationNamespaceTest < Minitest::Test
|
57
|
+
def test_namespace
|
58
|
+
test1 = TestNamespace2::Test.new(name: 'Test 1', email: 'test1@test.com', gender: 'M')
|
59
|
+
test2 = TestNamespace2::Test.new(name: 'Test 2', email: 'test2@test.com', gender: 'M')
|
60
|
+
sub_test1 = TestNamespace2::SubTest.new(name: 'Name 1', description: 'Description 1', comments: 'Comments 1')
|
61
|
+
sub_test2 = TestNamespace2::SubTest.new(name: 'Name 2', description: 'Description 2', comments: 'Comments 2')
|
62
|
+
test1.sub_test = sub_test1
|
63
|
+
test2.sub_test = sub_test2
|
64
|
+
|
65
|
+
array = [test1, test2]
|
66
|
+
serializer = ArraySerializer.new(array)
|
67
|
+
|
68
|
+
expected = [
|
69
|
+
{ name: 'Test 1', email: 'test1@test.com', sub_test: { name: 'Name 1', description: 'Description 1' } },
|
70
|
+
{ name: 'Test 2', email: 'test2@test.com', sub_test: { name: 'Name 2', description: 'Description 2' } }
|
71
|
+
]
|
72
|
+
|
73
|
+
assert_equal expected, serializer.serializable_array
|
74
|
+
assert_equal expected, serializer.as_json
|
52
75
|
end
|
53
76
|
end
|
54
77
|
|
@@ -4,7 +4,7 @@ module ActiveModel
|
|
4
4
|
class DefaultSerializer
|
5
5
|
class Test < Minitest::Test
|
6
6
|
def test_serialize_objects
|
7
|
-
|
7
|
+
assert_nil(DefaultSerializer.new(nil).serializable_object)
|
8
8
|
assert_equal(1, DefaultSerializer.new(1).serializable_object)
|
9
9
|
assert_equal('hi', DefaultSerializer.new('hi').serializable_object)
|
10
10
|
end
|
@@ -2,7 +2,7 @@ require 'test_helper'
|
|
2
2
|
|
3
3
|
module ActiveModel
|
4
4
|
class Serializer
|
5
|
-
class HasManyPolymorphicTest <
|
5
|
+
class HasManyPolymorphicTest < Minitest::Test
|
6
6
|
def setup
|
7
7
|
@association = MailSerializer._associations[:attachments]
|
8
8
|
@old_association = @association.dup
|
@@ -2,7 +2,7 @@ require 'test_helper'
|
|
2
2
|
|
3
3
|
module ActiveModel
|
4
4
|
class Serializer
|
5
|
-
class HasOnePolymorphicTest <
|
5
|
+
class HasOnePolymorphicTest < Minitest::Test
|
6
6
|
def setup
|
7
7
|
@association = InterviewSerializer._associations[:attachment]
|
8
8
|
@old_association = @association.dup
|
metadata
CHANGED
@@ -1,16 +1,16 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: active_model_serializers
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.9.
|
4
|
+
version: 0.9.13
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- José Valim
|
8
8
|
- Yehuda Katz
|
9
9
|
- Santiago Pastorino
|
10
|
-
autorequire:
|
10
|
+
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date:
|
13
|
+
date: 2024-09-17 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: activemodel
|
@@ -89,42 +89,19 @@ files:
|
|
89
89
|
- lib/active_model/serializer/version.rb
|
90
90
|
- lib/active_model/serializer_support.rb
|
91
91
|
- lib/active_model_serializers.rb
|
92
|
-
- lib/bulk_cache_fetcher.rb
|
93
|
-
- test/action_controller/http_cache_test.rb
|
94
|
-
- test/action_controller/regression_test.rb
|
95
92
|
- test/benchmark/app.rb
|
96
93
|
- test/benchmark/benchmarking_support.rb
|
97
94
|
- test/benchmark/bm_active_record.rb
|
98
|
-
- test/benchmark/bm_rails_cache.rb
|
99
95
|
- test/benchmark/setup.rb
|
100
|
-
- test/benchmark/tmp/miniprofiler/
|
101
|
-
- test/benchmark/tmp/miniprofiler/
|
102
|
-
- test/benchmark/tmp/miniprofiler/
|
103
|
-
- test/benchmark/tmp/miniprofiler/
|
104
|
-
- test/benchmark/tmp/miniprofiler/
|
105
|
-
- test/benchmark/tmp/miniprofiler/
|
106
|
-
- test/benchmark/tmp/miniprofiler/
|
107
|
-
- test/benchmark/tmp/miniprofiler/
|
108
|
-
- test/benchmark/tmp/miniprofiler/
|
109
|
-
- test/benchmark/tmp/miniprofiler/mp_timers_hqodkd691tbr7sbfdiez
|
110
|
-
- test/benchmark/tmp/miniprofiler/mp_timers_j7y5frtod7cw4qc4cear
|
111
|
-
- test/benchmark/tmp/miniprofiler/mp_timers_jpxzfgo92l24t7wzt8g1
|
112
|
-
- test/benchmark/tmp/miniprofiler/mp_timers_m78k2w11sd7ba5oh40rw
|
113
|
-
- test/benchmark/tmp/miniprofiler/mp_timers_mkvat4ehphrje9n2hu3t
|
114
|
-
- test/benchmark/tmp/miniprofiler/mp_timers_nd3ymt54l1ga22i2brn8
|
115
|
-
- test/benchmark/tmp/miniprofiler/mp_timers_o2dk1yhw6ez9jzxf6p0a
|
116
|
-
- test/benchmark/tmp/miniprofiler/mp_timers_p76i310zb4y12iqm5o0n
|
117
|
-
- test/benchmark/tmp/miniprofiler/mp_timers_pi3hvrrkfxnxl300wvah
|
118
|
-
- test/benchmark/tmp/miniprofiler/mp_timers_q4w5d86flb4u9tsadqvw
|
119
|
-
- test/benchmark/tmp/miniprofiler/mp_timers_sfa5nundogo63o056n5y
|
120
|
-
- test/benchmark/tmp/miniprofiler/mp_timers_tkjlmqeauf5gur2u5nob
|
121
|
-
- test/benchmark/tmp/miniprofiler/mp_timers_tngbj11ilv2i75rqn2d2
|
122
|
-
- test/benchmark/tmp/miniprofiler/mp_timers_u4haqgvgybvc1sb5nihw
|
123
|
-
- test/benchmark/tmp/miniprofiler/mp_timers_uc1b3hwqrd4q512gy6c9
|
124
|
-
- test/benchmark/tmp/miniprofiler/mp_timers_uwholuf0iix2vvbo2l3c
|
125
|
-
- test/benchmark/tmp/miniprofiler/mp_timers_waye238ygft3p4xvppc4
|
126
|
-
- test/benchmark/tmp/miniprofiler/mp_timers_ydwo7p117loo2ky40lk3
|
127
|
-
- test/benchmark/tmp/miniprofiler/mp_timers_zhgmyfizfa8slppitgua
|
96
|
+
- test/benchmark/tmp/miniprofiler/mp_timers_6eqewtfgrhitvq5gqm25
|
97
|
+
- test/benchmark/tmp/miniprofiler/mp_timers_8083sx03hu72pxz1a4d0
|
98
|
+
- test/benchmark/tmp/miniprofiler/mp_timers_fyz2gsml4z0ph9kpoy1c
|
99
|
+
- test/benchmark/tmp/miniprofiler/mp_timers_hjry5rc32imd42oxoi48
|
100
|
+
- test/benchmark/tmp/miniprofiler/mp_timers_m8fpoz2cvt3g9agz0bs3
|
101
|
+
- test/benchmark/tmp/miniprofiler/mp_timers_p92m2drnj1i568u3sta0
|
102
|
+
- test/benchmark/tmp/miniprofiler/mp_timers_qg52tpca3uesdfguee9i
|
103
|
+
- test/benchmark/tmp/miniprofiler/mp_timers_s15t1a6mvxe0z7vjv790
|
104
|
+
- test/benchmark/tmp/miniprofiler/mp_timers_x8kal3d17nfds6vp4kcj
|
128
105
|
- test/benchmark/tmp/miniprofiler/mp_views_127.0.0.1
|
129
106
|
- test/fixtures/active_record.rb
|
130
107
|
- test/fixtures/poro.rb
|
@@ -169,7 +146,7 @@ homepage: https://github.com/rails-api/active_model_serializers
|
|
169
146
|
licenses:
|
170
147
|
- MIT
|
171
148
|
metadata: {}
|
172
|
-
post_install_message:
|
149
|
+
post_install_message:
|
173
150
|
rdoc_options: []
|
174
151
|
require_paths:
|
175
152
|
- lib
|
@@ -184,48 +161,25 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
184
161
|
- !ruby/object:Gem::Version
|
185
162
|
version: '0'
|
186
163
|
requirements: []
|
187
|
-
|
188
|
-
|
189
|
-
signing_key:
|
164
|
+
rubygems_version: 3.3.7
|
165
|
+
signing_key:
|
190
166
|
specification_version: 4
|
191
167
|
summary: Bringing consistency and object orientation to model serialization. Works
|
192
168
|
great for client-side MVC frameworks!
|
193
169
|
test_files:
|
194
|
-
- test/action_controller/http_cache_test.rb
|
195
|
-
- test/action_controller/regression_test.rb
|
196
170
|
- test/benchmark/app.rb
|
197
171
|
- test/benchmark/benchmarking_support.rb
|
198
172
|
- test/benchmark/bm_active_record.rb
|
199
|
-
- test/benchmark/bm_rails_cache.rb
|
200
173
|
- test/benchmark/setup.rb
|
201
|
-
- test/benchmark/tmp/miniprofiler/
|
202
|
-
- test/benchmark/tmp/miniprofiler/
|
203
|
-
- test/benchmark/tmp/miniprofiler/
|
204
|
-
- test/benchmark/tmp/miniprofiler/
|
205
|
-
- test/benchmark/tmp/miniprofiler/
|
206
|
-
- test/benchmark/tmp/miniprofiler/
|
207
|
-
- test/benchmark/tmp/miniprofiler/
|
208
|
-
- test/benchmark/tmp/miniprofiler/
|
209
|
-
- test/benchmark/tmp/miniprofiler/
|
210
|
-
- test/benchmark/tmp/miniprofiler/mp_timers_hqodkd691tbr7sbfdiez
|
211
|
-
- test/benchmark/tmp/miniprofiler/mp_timers_j7y5frtod7cw4qc4cear
|
212
|
-
- test/benchmark/tmp/miniprofiler/mp_timers_jpxzfgo92l24t7wzt8g1
|
213
|
-
- test/benchmark/tmp/miniprofiler/mp_timers_m78k2w11sd7ba5oh40rw
|
214
|
-
- test/benchmark/tmp/miniprofiler/mp_timers_mkvat4ehphrje9n2hu3t
|
215
|
-
- test/benchmark/tmp/miniprofiler/mp_timers_nd3ymt54l1ga22i2brn8
|
216
|
-
- test/benchmark/tmp/miniprofiler/mp_timers_o2dk1yhw6ez9jzxf6p0a
|
217
|
-
- test/benchmark/tmp/miniprofiler/mp_timers_p76i310zb4y12iqm5o0n
|
218
|
-
- test/benchmark/tmp/miniprofiler/mp_timers_pi3hvrrkfxnxl300wvah
|
219
|
-
- test/benchmark/tmp/miniprofiler/mp_timers_q4w5d86flb4u9tsadqvw
|
220
|
-
- test/benchmark/tmp/miniprofiler/mp_timers_sfa5nundogo63o056n5y
|
221
|
-
- test/benchmark/tmp/miniprofiler/mp_timers_tkjlmqeauf5gur2u5nob
|
222
|
-
- test/benchmark/tmp/miniprofiler/mp_timers_tngbj11ilv2i75rqn2d2
|
223
|
-
- test/benchmark/tmp/miniprofiler/mp_timers_u4haqgvgybvc1sb5nihw
|
224
|
-
- test/benchmark/tmp/miniprofiler/mp_timers_uc1b3hwqrd4q512gy6c9
|
225
|
-
- test/benchmark/tmp/miniprofiler/mp_timers_uwholuf0iix2vvbo2l3c
|
226
|
-
- test/benchmark/tmp/miniprofiler/mp_timers_waye238ygft3p4xvppc4
|
227
|
-
- test/benchmark/tmp/miniprofiler/mp_timers_ydwo7p117loo2ky40lk3
|
228
|
-
- test/benchmark/tmp/miniprofiler/mp_timers_zhgmyfizfa8slppitgua
|
174
|
+
- test/benchmark/tmp/miniprofiler/mp_timers_6eqewtfgrhitvq5gqm25
|
175
|
+
- test/benchmark/tmp/miniprofiler/mp_timers_8083sx03hu72pxz1a4d0
|
176
|
+
- test/benchmark/tmp/miniprofiler/mp_timers_fyz2gsml4z0ph9kpoy1c
|
177
|
+
- test/benchmark/tmp/miniprofiler/mp_timers_hjry5rc32imd42oxoi48
|
178
|
+
- test/benchmark/tmp/miniprofiler/mp_timers_m8fpoz2cvt3g9agz0bs3
|
179
|
+
- test/benchmark/tmp/miniprofiler/mp_timers_p92m2drnj1i568u3sta0
|
180
|
+
- test/benchmark/tmp/miniprofiler/mp_timers_qg52tpca3uesdfguee9i
|
181
|
+
- test/benchmark/tmp/miniprofiler/mp_timers_s15t1a6mvxe0z7vjv790
|
182
|
+
- test/benchmark/tmp/miniprofiler/mp_timers_x8kal3d17nfds6vp4kcj
|
229
183
|
- test/benchmark/tmp/miniprofiler/mp_views_127.0.0.1
|
230
184
|
- test/fixtures/active_record.rb
|
231
185
|
- test/fixtures/poro.rb
|
data/lib/bulk_cache_fetcher.rb
DELETED
@@ -1,105 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
# https://github.com/justinweiss/bulk_cache_fetcher/blob/df1c83e06b9641b7ec3408ec577b37528021190f/lib/bulk_cache_fetcher.rb
|
3
|
-
# Fetches many objects from a cache in order. In the event that some
|
4
|
-
# objects can't be served from the cache, you will have the
|
5
|
-
# opportunity to fetch them in bulk. This allows you to preload and
|
6
|
-
# cache entire object hierarchies, which works particularly well with
|
7
|
-
# Rails' nested caching while avoiding the n+1 queries problem in the
|
8
|
-
# uncached case.
|
9
|
-
class BulkCacheFetcher
|
10
|
-
VERSION = '1.0.0'
|
11
|
-
|
12
|
-
# Creates a new bulk cache fetcher, backed by +cache+. Cache must
|
13
|
-
# respond to the standard Rails cache API, described on
|
14
|
-
# http://guides.rubyonrails.org/caching_with_rails.html
|
15
|
-
def initialize(cache)
|
16
|
-
@cache = cache
|
17
|
-
end
|
18
|
-
|
19
|
-
# Returns a list of objects identified by
|
20
|
-
# <tt>object_identifiers</tt>. +fetch+ will try to find the objects
|
21
|
-
# from the cache first. Identifiers for objects that aren't in the
|
22
|
-
# cache will be passed as an ordered list to <tt>finder_block</tt>,
|
23
|
-
# where you can find the objects as you see fit. These objects
|
24
|
-
# should be returned in the same order as the identifiers that were
|
25
|
-
# passed into the block, because they'll be cached under their
|
26
|
-
# respective keys. The objects returned by +fetch+ will be returned
|
27
|
-
# in the same order as the <tt>object_identifiers</tt> passed in.
|
28
|
-
#
|
29
|
-
# +options+ will be passed along unmodified when caching newly found
|
30
|
-
# objects, so you can use it for things like setting cache
|
31
|
-
# expiration.
|
32
|
-
def fetch(object_identifiers, options = {}, &finder_block)
|
33
|
-
object_identifiers = normalize(object_identifiers)
|
34
|
-
cached_keys_with_objects, uncached_identifiers = partition(object_identifiers)
|
35
|
-
found_objects = find(uncached_identifiers, options, &finder_block)
|
36
|
-
coalesce(cache_keys(object_identifiers), cached_keys_with_objects, found_objects)
|
37
|
-
end
|
38
|
-
|
39
|
-
private
|
40
|
-
|
41
|
-
# Splits a list of identifiers into two objects. The first is a hash
|
42
|
-
# of <tt>{cache_key: object}</tt> for all the objects we were able to serve
|
43
|
-
# from the cache. The second is a list of all of the identifiers for
|
44
|
-
# objects that weren't cached.
|
45
|
-
def partition(object_identifiers)
|
46
|
-
uncached_identifiers = object_identifiers.dup
|
47
|
-
|
48
|
-
cache_keys = cache_keys(object_identifiers)
|
49
|
-
cached_keys_with_objects = @cache.read_multi(*cache_keys)
|
50
|
-
|
51
|
-
cache_keys.each do |cache_key|
|
52
|
-
uncached_identifiers.delete(cache_key) if cached_keys_with_objects.key?(cache_key)
|
53
|
-
end
|
54
|
-
|
55
|
-
[cached_keys_with_objects, uncached_identifiers]
|
56
|
-
end
|
57
|
-
|
58
|
-
# Finds all of the objects identified by +identifiers+, using the
|
59
|
-
# +finder_block+. Will pass +options+ on to the cache.
|
60
|
-
def find(identifiers, options = {})
|
61
|
-
return [] if identifiers.empty?
|
62
|
-
Array(yield(identifiers)).tap do |objects|
|
63
|
-
verify_equal_key_and_value_counts!(identifiers, objects)
|
64
|
-
cache_all(identifiers, objects, options)
|
65
|
-
end
|
66
|
-
end
|
67
|
-
|
68
|
-
# Makes sure we have enough +identifiers+ to cache all of our
|
69
|
-
# +objects+, and vice-versa.
|
70
|
-
def verify_equal_key_and_value_counts!(identifiers, objects)
|
71
|
-
fail ArgumentError, 'You are returning too many objects from your cache block!' if objects.length > identifiers.length
|
72
|
-
fail ArgumentError, 'You are returning too few objects from your cache block!' if objects.length < identifiers.length
|
73
|
-
end
|
74
|
-
|
75
|
-
# Caches all +values+ under their respective +keys+.
|
76
|
-
def cache_all(keys, values, options = {})
|
77
|
-
keys.zip(values) { |k, v| @cache.write(cache_key(k), v, options) }
|
78
|
-
end
|
79
|
-
|
80
|
-
# Given a list of +cache_keys+, either find associated objects from
|
81
|
-
# +cached_keys_with_objects, or grab them from +found_objects+, in
|
82
|
-
# order.
|
83
|
-
def coalesce(cache_keys, cached_keys_with_objects, found_objects)
|
84
|
-
found_objects = Array(found_objects)
|
85
|
-
cache_keys.map { |key| cached_keys_with_objects.fetch(key) { found_objects.shift } }
|
86
|
-
end
|
87
|
-
|
88
|
-
# Returns the part of the identifier that we can use as the cache
|
89
|
-
# key. For simple identifiers, it's just the identifier, for
|
90
|
-
# identifiers with extra information attached, it's the first part
|
91
|
-
# of the identifier.
|
92
|
-
def cache_key(identifier)
|
93
|
-
Array(identifier).first
|
94
|
-
end
|
95
|
-
|
96
|
-
# Returns the cache keys for all of the +identifiers+.
|
97
|
-
def cache_keys(identifiers)
|
98
|
-
identifiers.map { |identifier| cache_key(identifier) }
|
99
|
-
end
|
100
|
-
|
101
|
-
# Makes sure we can iterate over identifiers.
|
102
|
-
def normalize(identifiers)
|
103
|
-
identifiers.respond_to?(:each) ? identifiers : Array(identifiers)
|
104
|
-
end
|
105
|
-
end
|
@@ -1,56 +0,0 @@
|
|
1
|
-
# require 'test_helper'
|
2
|
-
#
|
3
|
-
# # https://github.com/rails/rails/blob/4-2-stable/actionpack/lib/action_dispatch/testing/integration.rb
|
4
|
-
# # rubocop:disable Style/ClassAndModuleChildren:
|
5
|
-
# class ActionController::Serialization::HttpCacheTest < ActionController::TestCase
|
6
|
-
# # class ActionController::Serialization::HttpCacheTest < ActionDispatch::IntegrationTest
|
7
|
-
# class HttpCacheTestController < ActionController::Base
|
8
|
-
# class Model < ActiveModelSerializers::Model
|
9
|
-
# attr_accessor :name, :description, :comments
|
10
|
-
# end
|
11
|
-
# class ModelSerializer < ActiveModel::Serializer
|
12
|
-
# attributes :name, :description, :comments
|
13
|
-
# end
|
14
|
-
#
|
15
|
-
# def render_as_serializable_object
|
16
|
-
# render serialization_options.merge!(json: model)
|
17
|
-
# end
|
18
|
-
#
|
19
|
-
# def render_as_json_string
|
20
|
-
# json = ActiveModelSerializers::SerializableResource.new(model, serialization_options).to_json
|
21
|
-
# render json: json
|
22
|
-
# end
|
23
|
-
#
|
24
|
-
# private
|
25
|
-
#
|
26
|
-
# def model
|
27
|
-
# Model.new(name: 'Name 1', description: 'Description 1', comments: 'Comments 1')
|
28
|
-
# end
|
29
|
-
#
|
30
|
-
# def serialization_options
|
31
|
-
# { serializer: ModelSerializer, adapter: :json }
|
32
|
-
# end
|
33
|
-
# end
|
34
|
-
#
|
35
|
-
# tests HttpCacheTestController
|
36
|
-
#
|
37
|
-
# DATE = 'Date'.freeze
|
38
|
-
# LAST_MODIFIED = 'Last-Modified'.freeze
|
39
|
-
# ETAG = 'ETag'.freeze
|
40
|
-
# CACHE_CONTROL = 'Cache-Control'.freeze
|
41
|
-
# SPECIAL_KEYS = Set.new(%w(extras no-cache max-age public must-revalidate))
|
42
|
-
# def test_render_as_serializable_object
|
43
|
-
# 10.times do
|
44
|
-
# get :render_as_serializable_object
|
45
|
-
# end
|
46
|
-
# p [@response.etag?, @response.last_modified, @response.date, @response.headers[CACHE_CONTROL], @response.headers[ETAG], @response.headers[LAST_MODIFIED], @response.headers[DATE]]
|
47
|
-
# end
|
48
|
-
#
|
49
|
-
# def test_render_as_json_string
|
50
|
-
# 10.times do
|
51
|
-
# get :render_as_json_string
|
52
|
-
# end
|
53
|
-
# p [@response.etag?, @response.last_modified, @response.date, @response.headers[CACHE_CONTROL], @response.headers[ETAG], @response.headers[LAST_MODIFIED], @response.headers[DATE]]
|
54
|
-
# end
|
55
|
-
# end
|
56
|
-
# # rubocop:enable Style/ClassAndModuleChildren:
|
@@ -1,35 +0,0 @@
|
|
1
|
-
# require 'test_helper'
|
2
|
-
#
|
3
|
-
# module ActionController
|
4
|
-
# module Serialization
|
5
|
-
# class ImplicitSerializerTest < ActionController::TestCase
|
6
|
-
# class PostWithoutSerializer < ActiveRecord::Base
|
7
|
-
# self.table_name = :posts
|
8
|
-
# end
|
9
|
-
# class ImplicitSerializationTestController < ActionController::Base
|
10
|
-
# def render_record_without_serializer
|
11
|
-
# @post = PostWithoutSerializer.new(title: 'Title', body: 'Body')
|
12
|
-
# render json: @post
|
13
|
-
# end
|
14
|
-
# end
|
15
|
-
#
|
16
|
-
# tests ImplicitSerializationTestController
|
17
|
-
#
|
18
|
-
# def test_record_without_serializer
|
19
|
-
# with_adapter :json do
|
20
|
-
# get :render_record_without_serializer
|
21
|
-
# end
|
22
|
-
#
|
23
|
-
# expected = {}
|
24
|
-
# PostWithoutSerializer.column_names.each { |field| expected[field] ||= nil }
|
25
|
-
# expected.update(
|
26
|
-
# title: 'Title',
|
27
|
-
# body: 'Body'
|
28
|
-
# )
|
29
|
-
#
|
30
|
-
# assert_equal 'application/json', @response.content_type
|
31
|
-
# assert_equal expected.to_json, @response.body
|
32
|
-
# end
|
33
|
-
# end
|
34
|
-
# end
|
35
|
-
# end
|
@@ -1,141 +0,0 @@
|
|
1
|
-
require 'bundler/setup'
|
2
|
-
require_relative './benchmarking_support'
|
3
|
-
require_relative './app'
|
4
|
-
|
5
|
-
time = 10
|
6
|
-
cache_store = ActiveSupport::Cache.lookup_store(:memory_store)
|
7
|
-
comments = (0..50).map do |i|
|
8
|
-
Comment.new(id: i, body: 'ZOMG A COMMENT')
|
9
|
-
end
|
10
|
-
author = Author.new(id: 42, first_name: 'Joao', last_name: 'Moura')
|
11
|
-
model = Post.new(id: 1337, title: 'New Post', blog: nil, body: 'Body', comments: comments, author: author)
|
12
|
-
|
13
|
-
define_method :json do
|
14
|
-
model.to_json
|
15
|
-
end
|
16
|
-
define_method :cached_json do
|
17
|
-
parts = []
|
18
|
-
parts << 'key_name'
|
19
|
-
parts << 'adapter_name'
|
20
|
-
cache_key = parts.join('/')
|
21
|
-
cache_store.fetch(cache_key) { model.to_json }
|
22
|
-
end
|
23
|
-
define_method :ams do
|
24
|
-
ActiveModelSerializers::SerializableResource.new(model, adapter: :json, serializer: PostSerializer).as_json
|
25
|
-
end
|
26
|
-
define_method :cached_ams do
|
27
|
-
ActiveModelSerializers::SerializableResource.new(model, adapter: :json, serializer: CachingPostSerializer).as_json
|
28
|
-
end
|
29
|
-
def as_json(serializer_instance, adapter_instance, fields, includes = '*')
|
30
|
-
if serializer_instance.respond_to?(:each)
|
31
|
-
return serializer_instance.map do |each_serializer|
|
32
|
-
as_json(each_serializer, adapter_instance, fields, includes)
|
33
|
-
end
|
34
|
-
end
|
35
|
-
cache_key = serializer_instance.cache_key(adapter_instance)
|
36
|
-
include_tree = includes || ActiveModel::Serializer::IncludeTree.from_include_args(includes)
|
37
|
-
cache_store = ActiveModelSerializers.config.cache_store
|
38
|
-
json = cache_store.fetch(cache_key) do
|
39
|
-
serializer_instance.attributes(fields)
|
40
|
-
end
|
41
|
-
serializer_instance.associations(include_tree).each do |association|
|
42
|
-
# FIXME: yields each association twice
|
43
|
-
json[association.key] ||= as_json(association.serializer, adapter_instance, [], includes[association.key])
|
44
|
-
end
|
45
|
-
json
|
46
|
-
end
|
47
|
-
|
48
|
-
define_method :cached_virtual_ams do
|
49
|
-
### OMG
|
50
|
-
post_serializer = CachingPostSerializer.new(model)
|
51
|
-
adapter_instance = ActiveModelSerializers::Adapter::Attributes.new(post_serializer)
|
52
|
-
fields = nil
|
53
|
-
includes = ActiveModel::Serializer::IncludeTree.from_include_args('*')
|
54
|
-
{ post: as_json(post_serializer, adapter_instance, fields, includes) }
|
55
|
-
# parts = []
|
56
|
-
# parts << 'ams_blog'
|
57
|
-
# parts << 'attributes'
|
58
|
-
# cache_key = parts.join('/')
|
59
|
-
# cache_store.fetch(cache_key) do
|
60
|
-
# include_tree = ActiveModel::Serializer::IncludeTree.from_include_args('*')
|
61
|
-
# post_serializer = CachingPostSerializer.new(model)
|
62
|
-
# json = { post: post_serializer.attributes }
|
63
|
-
# post_serializer.associations(include_tree).each do |association|
|
64
|
-
# # FIXME: yields each association twice
|
65
|
-
# json[:post][association.key] ||=
|
66
|
-
# case association.key
|
67
|
-
# when :comments
|
68
|
-
# cache_store.fetch(%w(ams_comments attributes).join('/')) do
|
69
|
-
# association.serializer.map(&:attributes)
|
70
|
-
# end
|
71
|
-
# when :blog
|
72
|
-
# association.serializer.attributes
|
73
|
-
# when :author
|
74
|
-
# cache_store.fetch(%w(ams_author attributes).join('/')) do
|
75
|
-
# association.serializer.attributes
|
76
|
-
# end
|
77
|
-
# else
|
78
|
-
# fail ArgumentError, "unexpected association #{association}"
|
79
|
-
# end
|
80
|
-
# end
|
81
|
-
# json
|
82
|
-
# end
|
83
|
-
end
|
84
|
-
puts JSON.pretty_generate(
|
85
|
-
equality: { cached_ams: ams == cached_ams, cached_virtual_ams: ams == cached_virtual_ams },
|
86
|
-
ams: ams,
|
87
|
-
cached_ams: cached_ams,
|
88
|
-
cached_virtual_ams: cached_virtual_ams
|
89
|
-
)
|
90
|
-
|
91
|
-
{
|
92
|
-
# 'cached json' => { disable_gc: true, send: :cached_json },
|
93
|
-
# 'json' => { disable_gc: true, send: :json },
|
94
|
-
# 'cached ams' => { disable_gc: true, send: :cached_ams },
|
95
|
-
'cached virtual ams' => { disable_gc: true, send: :cached_virtual_ams },
|
96
|
-
'ams' => { disable_gc: true, send: :ams }
|
97
|
-
}.each do |label, options|
|
98
|
-
Benchmark.ams(label, time: time, disable_gc: options[:disable_gc]) do
|
99
|
-
send(options[:send])
|
100
|
-
end
|
101
|
-
end
|
102
|
-
__END__
|
103
|
-
cached json 121321.3745504354/ips; 16 objects
|
104
|
-
json 1177.243210850789/ips; 1984 objects
|
105
|
-
cached ams 251.90341731442047/ips; 5879 objects
|
106
|
-
cached virtual ams 89169.87612473704/ips; 16 objects
|
107
|
-
ams 598.9890084759535/ips; 2348 objects
|
108
|
-
Benchmark results:
|
109
|
-
{
|
110
|
-
"commit_hash": "aa0be94",
|
111
|
-
"version": "0.10.0.rc5",
|
112
|
-
"rails_version": "4.2.5.1",
|
113
|
-
"benchmark_run[environment]": "2.2.3p173",
|
114
|
-
"runs": [
|
115
|
-
{
|
116
|
-
"benchmark_type[category]": "cached json",
|
117
|
-
"benchmark_run[result][iterations_per_second]": 121321.375,
|
118
|
-
"benchmark_run[result][total_allocated_objects_per_iteration]": 16
|
119
|
-
},
|
120
|
-
{
|
121
|
-
"benchmark_type[category]": "json",
|
122
|
-
"benchmark_run[result][iterations_per_second]": 1177.243,
|
123
|
-
"benchmark_run[result][total_allocated_objects_per_iteration]": 1984
|
124
|
-
},
|
125
|
-
{
|
126
|
-
"benchmark_type[category]": "cached ams",
|
127
|
-
"benchmark_run[result][iterations_per_second]": 251.903,
|
128
|
-
"benchmark_run[result][total_allocated_objects_per_iteration]": 5879
|
129
|
-
},
|
130
|
-
{
|
131
|
-
"benchmark_type[category]": "cached virtual ams",
|
132
|
-
"benchmark_run[result][iterations_per_second]": 89169.876,
|
133
|
-
"benchmark_run[result][total_allocated_objects_per_iteration]": 16
|
134
|
-
},
|
135
|
-
{
|
136
|
-
"benchmark_type[category]": "ams",
|
137
|
-
"benchmark_run[result][iterations_per_second]": 598.989,
|
138
|
-
"benchmark_run[result][total_allocated_objects_per_iteration]": 2348
|
139
|
-
}
|
140
|
-
]
|
141
|
-
}
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|