active_model_serializers 0.9.6 → 0.9.7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +5 -1
- data/README.md +3 -3
- data/lib/active_model/array_serializer.rb +0 -5
- data/lib/active_model/default_serializer.rb +2 -6
- data/lib/active_model/serializable.rb +12 -15
- data/lib/active_model/serializer.rb +10 -2
- data/lib/active_model/serializer/railtie.rb +4 -0
- data/lib/active_model/serializer/version.rb +1 -1
- data/lib/bulk_cache_fetcher.rb +2 -1
- data/test/action_controller/http_cache_test.rb +56 -56
- data/test/action_controller/regression_test.rb +35 -0
- data/test/benchmark/app.rb +60 -0
- data/test/benchmark/benchmarking_support.rb +67 -0
- data/test/benchmark/bm_active_record.rb +41 -0
- data/test/benchmark/setup.rb +75 -0
- data/test/fixtures/poro.rb +1 -1
- data/test/unit/active_model/serilizable_test.rb +50 -0
- metadata +28 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2f73f5aff52f42003b604fcc209782d1b074eb9a
|
4
|
+
data.tar.gz: 0fce31e1d5f8f01da8c0c9d70c30fee124dc87ff
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 983ed0d1faf8a9e4cb9cf65e4d71fdc5064016e42190a81aa96f73a37e1e342eecead421ebe69c04cca27db142a622eb966e9fc04b79cc152af5b744d6f97812
|
7
|
+
data.tar.gz: 97accf62bff15dc099483199c8ca58c974fc2ee227f64bdbd10223924cdbaa923d4fb59c5ea5a8973fb5612c50e8ef9abf50f300cc8b6f64b80dd9b3a181829f
|
data/CHANGELOG.md
CHANGED
@@ -1,6 +1,10 @@
|
|
1
1
|
## 0.09.x
|
2
2
|
|
3
|
-
### [0-9-stable](https://github.com/rails-api/active_model_serializers/compare/v0.9.
|
3
|
+
### [0-9-stable](https://github.com/rails-api/active_model_serializers/compare/v0.9.7...0-9-stable)
|
4
|
+
|
5
|
+
### [v0.9.7 (2017-05-01)](https://github.com/rails-api/active_model_serializers/compare/v0.9.6...v0.9.7)
|
6
|
+
|
7
|
+
- [#2080](https://github.com/rails-api/active_model_serializers/pull/2080) remove `{ payload: nil }` from `!serialize.active_model_serializers` ActiveSupport::Notification. `payload` never had a value. Changes, for example `{ serializer: 'ActiveModel::DefaultSerializer', payload: nil }` to be `{ serializer: 'ActiveModel::DefaultSerializer' }` (@yosiat)
|
4
8
|
|
5
9
|
### [v0.9.6 (2017-01-10)](https://github.com/rails-api/active_model_serializers/compare/v0.9.5...v0.9.6)
|
6
10
|
|
data/README.md
CHANGED
@@ -251,11 +251,11 @@ BlogSerializer.new(object, key_format: :lower_camel)
|
|
251
251
|
|
252
252
|
You can specify that serializers use unsuffixed names as association keys by default.
|
253
253
|
|
254
|
-
|
254
|
+
```ruby
|
255
255
|
ActiveModel::Serializer.setup do |config|
|
256
256
|
config.default_key_type = :name
|
257
257
|
end
|
258
|
-
|
258
|
+
```
|
259
259
|
|
260
260
|
This will build association keys like `comments` or `author` instead of `comment_ids` or `author_id`.
|
261
261
|
|
@@ -932,7 +932,7 @@ now generates:
|
|
932
932
|
class PostSerializer < ApplicationSerializer
|
933
933
|
attributes :id
|
934
934
|
end
|
935
|
-
|
935
|
+
```
|
936
936
|
|
937
937
|
# Design and Implementation Guidelines
|
938
938
|
|
@@ -15,18 +15,14 @@ module ActiveModel
|
|
15
15
|
end
|
16
16
|
|
17
17
|
def as_json(options={})
|
18
|
-
instrument
|
18
|
+
instrument do
|
19
19
|
return [] if @object.nil? && @wrap_in_array
|
20
20
|
hash = @object.as_json
|
21
21
|
@wrap_in_array ? [hash] : hash
|
22
22
|
end
|
23
23
|
end
|
24
|
+
|
24
25
|
alias serializable_hash as_json
|
25
26
|
alias serializable_object as_json
|
26
|
-
|
27
|
-
private
|
28
|
-
def instrumentation_keys
|
29
|
-
[:object, :wrap_in_array]
|
30
|
-
end
|
31
27
|
end
|
32
28
|
end
|
@@ -2,12 +2,14 @@ require 'active_model/serializable/utils'
|
|
2
2
|
|
3
3
|
module ActiveModel
|
4
4
|
module Serializable
|
5
|
+
INSTRUMENTATION_KEY = '!serialize.active_model_serializers'.freeze
|
6
|
+
|
5
7
|
def self.included(base)
|
6
8
|
base.extend Utils
|
7
9
|
end
|
8
10
|
|
9
11
|
def as_json(options={})
|
10
|
-
instrument
|
12
|
+
instrument do
|
11
13
|
if root = options.fetch(:root, json_key)
|
12
14
|
hash = { root => serializable_object(options) }
|
13
15
|
hash.merge!(serializable_data)
|
@@ -19,9 +21,7 @@ module ActiveModel
|
|
19
21
|
end
|
20
22
|
|
21
23
|
def serializable_object_with_notification(options={})
|
22
|
-
instrument(
|
23
|
-
serializable_object(options)
|
24
|
-
end
|
24
|
+
instrument { serializable_object(options) }
|
25
25
|
end
|
26
26
|
|
27
27
|
def serializable_data
|
@@ -33,7 +33,11 @@ module ActiveModel
|
|
33
33
|
end
|
34
34
|
|
35
35
|
def namespace
|
36
|
-
|
36
|
+
if module_name = get_namespace
|
37
|
+
Serializer.serializers_cache.fetch_or_store(module_name) do
|
38
|
+
Utils._const_get(module_name)
|
39
|
+
end
|
40
|
+
end
|
37
41
|
end
|
38
42
|
|
39
43
|
def embedded_in_root_associations
|
@@ -47,16 +51,9 @@ module ActiveModel
|
|
47
51
|
modules[0..-2].join('::') if modules.size > 1
|
48
52
|
end
|
49
53
|
|
50
|
-
def instrument(
|
51
|
-
payload =
|
52
|
-
|
53
|
-
payload
|
54
|
-
end
|
55
|
-
ActiveSupport::Notifications.instrument("#{action}.active_model_serializers", payload, &block)
|
56
|
-
end
|
57
|
-
|
58
|
-
def instrumentation_keys
|
59
|
-
[:object, :scope, :root, :meta_key, :meta, :wrap_in_array, :only, :except, :key_format]
|
54
|
+
def instrument(&block)
|
55
|
+
payload = { serializer: self.class.name }
|
56
|
+
ActiveSupport::Notifications.instrument(INSTRUMENTATION_KEY, payload, &block)
|
60
57
|
end
|
61
58
|
end
|
62
59
|
end
|
@@ -4,6 +4,7 @@ require 'active_model/serializer/association'
|
|
4
4
|
require 'active_model/serializer/config'
|
5
5
|
|
6
6
|
require 'thread'
|
7
|
+
require 'concurrent/map'
|
7
8
|
|
8
9
|
module ActiveModel
|
9
10
|
class Serializer
|
@@ -65,7 +66,10 @@ end
|
|
65
66
|
ArraySerializer
|
66
67
|
end
|
67
68
|
else
|
68
|
-
|
69
|
+
klass_name = build_serializer_class(resource, options)
|
70
|
+
Serializer.serializers_cache.fetch_or_store(klass_name) do
|
71
|
+
_const_get(klass_name)
|
72
|
+
end
|
69
73
|
end
|
70
74
|
end
|
71
75
|
|
@@ -100,6 +104,10 @@ end
|
|
100
104
|
associate(Association::HasMany, *attrs)
|
101
105
|
end
|
102
106
|
|
107
|
+
def serializers_cache
|
108
|
+
@serializers_cache ||= Concurrent::Map.new
|
109
|
+
end
|
110
|
+
|
103
111
|
private
|
104
112
|
|
105
113
|
def strip_attribute(attr)
|
@@ -203,7 +211,7 @@ end
|
|
203
211
|
if included_associations.include? name
|
204
212
|
association_serializer = build_serializer(association)
|
205
213
|
# we must do this always because even if the current association is not
|
206
|
-
#
|
214
|
+
# embedded in root, it might have its own associations that are embedded in root
|
207
215
|
hash.merge!(association_serializer.embedded_in_root_associations) do |key, oldval, newval|
|
208
216
|
if oldval.respond_to?(:to_ary)
|
209
217
|
[oldval, newval].flatten.uniq
|
data/lib/bulk_cache_fetcher.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
# https://github.com/justinweiss/bulk_cache_fetcher/blob/df1c83e06b9641b7ec3408ec577b37528021190f/lib/bulk_cache_fetcher.rb
|
2
3
|
# Fetches many objects from a cache in order. In the event that some
|
3
4
|
# objects can't be served from the cache, you will have the
|
@@ -6,7 +7,7 @@
|
|
6
7
|
# Rails' nested caching while avoiding the n+1 queries problem in the
|
7
8
|
# uncached case.
|
8
9
|
class BulkCacheFetcher
|
9
|
-
VERSION = '1.0.0'
|
10
|
+
VERSION = '1.0.0'
|
10
11
|
|
11
12
|
# Creates a new bulk cache fetcher, backed by +cache+. Cache must
|
12
13
|
# respond to the standard Rails cache API, described on
|
@@ -1,56 +1,56 @@
|
|
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
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
end
|
56
|
-
# rubocop:enable Style/ClassAndModuleChildren:
|
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:
|
@@ -0,0 +1,35 @@
|
|
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
|
@@ -0,0 +1,60 @@
|
|
1
|
+
# https://github.com/rails-api/active_model_serializers/pull/872
|
2
|
+
# approx ref 792fb8a9053f8db3c562dae4f40907a582dd1720 to test against
|
3
|
+
require 'bundler/setup'
|
4
|
+
|
5
|
+
require 'rails'
|
6
|
+
require 'active_model'
|
7
|
+
require 'active_support'
|
8
|
+
require 'active_support/json'
|
9
|
+
require 'action_controller'
|
10
|
+
require 'action_controller/test_case'
|
11
|
+
require 'action_controller/railtie'
|
12
|
+
abort "Rails application already defined: #{Rails.application.class}" if Rails.application
|
13
|
+
|
14
|
+
class NullLogger < Logger
|
15
|
+
def initialize(*_args)
|
16
|
+
end
|
17
|
+
|
18
|
+
def add(*_args, &_block)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
class BenchmarkLogger < ActiveSupport::Logger
|
22
|
+
def initialize
|
23
|
+
@file = StringIO.new
|
24
|
+
super(@file)
|
25
|
+
end
|
26
|
+
|
27
|
+
def messages
|
28
|
+
@file.rewind
|
29
|
+
@file.read
|
30
|
+
end
|
31
|
+
end
|
32
|
+
# ref: https://gist.github.com/bf4/8744473
|
33
|
+
class BenchmarkApp < Rails::Application
|
34
|
+
# Set up production configuration
|
35
|
+
config.eager_load = true
|
36
|
+
config.cache_classes = true
|
37
|
+
# CONFIG: CACHE_ON={on,off}
|
38
|
+
config.action_controller.perform_caching = ENV['CACHE_ON'] != 'off'
|
39
|
+
config.action_controller.cache_store = ActiveSupport::Cache.lookup_store(:memory_store)
|
40
|
+
|
41
|
+
config.active_support.test_order = :random
|
42
|
+
config.secret_token = 'S' * 30
|
43
|
+
config.secret_key_base = 'abc123'
|
44
|
+
config.consider_all_requests_local = false
|
45
|
+
|
46
|
+
# otherwise deadlock occurred
|
47
|
+
config.middleware.delete 'Rack::Lock'
|
48
|
+
|
49
|
+
# to disable log files
|
50
|
+
config.logger = NullLogger.new
|
51
|
+
config.active_support.deprecation = :log
|
52
|
+
config.log_level = :info
|
53
|
+
end
|
54
|
+
|
55
|
+
require 'active_model_serializers'
|
56
|
+
|
57
|
+
# Initialize app before any serializers are defined, for running across revisions.
|
58
|
+
# ref: https://github.com/rails-api/active_model_serializers/pull/1478
|
59
|
+
Rails.application.initialize!
|
60
|
+
|
@@ -0,0 +1,67 @@
|
|
1
|
+
require 'benchmark/ips'
|
2
|
+
require 'json'
|
3
|
+
|
4
|
+
# Add benchmarking runner from ruby-bench-suite
|
5
|
+
# https://github.com/ruby-bench/ruby-bench-suite/blob/master/rails/benchmarks/support/benchmark_rails.rb
|
6
|
+
module Benchmark
|
7
|
+
module ActiveModelSerializers
|
8
|
+
module TestMethods
|
9
|
+
def request(method, path)
|
10
|
+
response = Rack::MockRequest.new(BenchmarkApp).send(method, path)
|
11
|
+
if response.status.in?([404, 500])
|
12
|
+
fail "omg, #{method}, #{path}, '#{response.status}', '#{response.body}'"
|
13
|
+
end
|
14
|
+
response
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
# extend Benchmark with an `ams` method
|
19
|
+
def ams(label = nil, time:, disable_gc: true, warmup: 3, &block)
|
20
|
+
fail ArgumentError.new, 'block should be passed' unless block_given?
|
21
|
+
|
22
|
+
if disable_gc
|
23
|
+
GC.disable
|
24
|
+
else
|
25
|
+
GC.enable
|
26
|
+
end
|
27
|
+
|
28
|
+
report = Benchmark.ips(time, warmup, true) do |x|
|
29
|
+
x.report(label) { yield }
|
30
|
+
end
|
31
|
+
|
32
|
+
entry = report.entries.first
|
33
|
+
|
34
|
+
output = {
|
35
|
+
label: label,
|
36
|
+
version: ::ActiveModel::Serializer::VERSION.to_s,
|
37
|
+
rails_version: ::Rails.version.to_s,
|
38
|
+
iterations_per_second: entry.ips,
|
39
|
+
iterations_per_second_standard_deviation: entry.error_percentage,
|
40
|
+
total_allocated_objects_per_iteration: count_total_allocated_objects(&block)
|
41
|
+
}.to_json
|
42
|
+
|
43
|
+
puts output
|
44
|
+
output
|
45
|
+
end
|
46
|
+
|
47
|
+
def count_total_allocated_objects
|
48
|
+
if block_given?
|
49
|
+
key =
|
50
|
+
if RUBY_VERSION < '2.2'
|
51
|
+
:total_allocated_object
|
52
|
+
else
|
53
|
+
:total_allocated_objects
|
54
|
+
end
|
55
|
+
|
56
|
+
before = GC.stat[key]
|
57
|
+
yield
|
58
|
+
after = GC.stat[key]
|
59
|
+
after - before
|
60
|
+
else
|
61
|
+
-1
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
extend Benchmark::ActiveModelSerializers
|
67
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require_relative './benchmarking_support'
|
2
|
+
require_relative './app'
|
3
|
+
require_relative './setup'
|
4
|
+
|
5
|
+
time = 10
|
6
|
+
disable_gc = true
|
7
|
+
|
8
|
+
|
9
|
+
|
10
|
+
authors_query = Author.preload(:posts).preload(:profile)
|
11
|
+
author = authors_query.first
|
12
|
+
authors = authors_query.to_a
|
13
|
+
|
14
|
+
|
15
|
+
Benchmark.ams('Single: DefaultSerializer', time: time, disable_gc: disable_gc) do
|
16
|
+
ActiveModel::DefaultSerializer.new(author).to_json
|
17
|
+
end
|
18
|
+
|
19
|
+
Benchmark.ams('ArraySerializer', time: time, disable_gc: disable_gc) do
|
20
|
+
ActiveModel::ArraySerializer.new(authors).to_json
|
21
|
+
end
|
22
|
+
|
23
|
+
Benchmark.ams('ArraySerializer: each_serializer: DefaultSerializer', time: time, disable_gc: disable_gc) do
|
24
|
+
ActiveModel::ArraySerializer.new(authors, each_serializer:ActiveModel::DefaultSerializer).to_json
|
25
|
+
end
|
26
|
+
|
27
|
+
Benchmark.ams('FlatAuthorSerializer', time: time, disable_gc: disable_gc) do
|
28
|
+
FlatAuthorSerializer.new(author).to_json
|
29
|
+
end
|
30
|
+
|
31
|
+
Benchmark.ams('ArraySerializer: each_serializer: FlatAuthorSerializer', time: time, disable_gc: disable_gc) do
|
32
|
+
ActiveModel::ArraySerializer.new(authors, each_serializer: FlatAuthorSerializer).to_json
|
33
|
+
end
|
34
|
+
|
35
|
+
Benchmark.ams('AuthorWithDefaultRelationshipsSerializer', time: time, disable_gc: disable_gc) do
|
36
|
+
AuthorWithDefaultRelationshipsSerializer.new(author).to_json
|
37
|
+
end
|
38
|
+
|
39
|
+
Benchmark.ams('ArraySerializer: each_serializer: AuthorWithDefaultRelationshipsSerializer', time: time, disable_gc: disable_gc) do
|
40
|
+
ActiveModel::ArraySerializer.new(authors, each_serializer: AuthorWithDefaultRelationshipsSerializer).to_json
|
41
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
###########################################
|
2
|
+
# Setup active record models
|
3
|
+
##########################################
|
4
|
+
require 'active_record'
|
5
|
+
require 'sqlite3'
|
6
|
+
|
7
|
+
|
8
|
+
# Change the following to reflect your database settings
|
9
|
+
ActiveRecord::Base.establish_connection(
|
10
|
+
adapter: 'sqlite3',
|
11
|
+
database: ':memory:'
|
12
|
+
)
|
13
|
+
|
14
|
+
# Don't show migration output when constructing fake db
|
15
|
+
ActiveRecord::Migration.verbose = false
|
16
|
+
|
17
|
+
ActiveRecord::Schema.define do
|
18
|
+
create_table :authors, force: true do |t|
|
19
|
+
t.string :name
|
20
|
+
end
|
21
|
+
|
22
|
+
create_table :posts, force: true do |t|
|
23
|
+
t.text :body
|
24
|
+
t.string :title
|
25
|
+
t.references :author
|
26
|
+
end
|
27
|
+
|
28
|
+
create_table :profiles, force: true do |t|
|
29
|
+
t.text :project_url
|
30
|
+
t.text :bio
|
31
|
+
t.date :birthday
|
32
|
+
t.references :author
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
class Author < ActiveRecord::Base
|
37
|
+
has_one :profile
|
38
|
+
has_many :posts
|
39
|
+
end
|
40
|
+
|
41
|
+
class Post < ActiveRecord::Base
|
42
|
+
belongs_to :author
|
43
|
+
end
|
44
|
+
|
45
|
+
class Profile < ActiveRecord::Base
|
46
|
+
belongs_to :author
|
47
|
+
end
|
48
|
+
|
49
|
+
# Build out the data to serialize
|
50
|
+
author = Author.create(name: 'Preston Sego')
|
51
|
+
Profile.create(project_url: 'https://github.com/NullVoxPopuli', author: author)
|
52
|
+
50.times do
|
53
|
+
Post.create(
|
54
|
+
body: 'something about how password restrictions are evil, and less secure, and with the math to prove it.',
|
55
|
+
title: 'Your bank is does not know how to do security',
|
56
|
+
author: author
|
57
|
+
)
|
58
|
+
end
|
59
|
+
|
60
|
+
ActiveModel::Serializer.root = false
|
61
|
+
ActiveModel::ArraySerializer.root = false
|
62
|
+
|
63
|
+
class FlatAuthorSerializer < ActiveModel::Serializer
|
64
|
+
attributes :id, :name
|
65
|
+
end
|
66
|
+
|
67
|
+
class AuthorWithDefaultRelationshipsSerializer < ActiveModel::Serializer
|
68
|
+
attributes :id, :name
|
69
|
+
|
70
|
+
has_one :profile
|
71
|
+
has_many :posts
|
72
|
+
end
|
73
|
+
|
74
|
+
# For debugging SQL output
|
75
|
+
#ActiveRecord::Base.logger = Logger.new(STDERR)
|
data/test/fixtures/poro.rb
CHANGED
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
module ActiveModel
|
4
|
+
class SerializableTest
|
5
|
+
class InstrumentationTest < Minitest::Test
|
6
|
+
def setup
|
7
|
+
@events = []
|
8
|
+
|
9
|
+
@subscriber = ActiveSupport::Notifications.subscribe('!serialize.active_model_serializers') do |name, start, finish, id, payload|
|
10
|
+
@events << { name: name, serializer: payload[:serializer] }
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def teardown
|
15
|
+
ActiveSupport::Notifications.unsubscribe(@subscriber) if defined?(@subscriber)
|
16
|
+
end
|
17
|
+
|
18
|
+
def test_instruments_default_serializer
|
19
|
+
DefaultSerializer.new(1).as_json
|
20
|
+
|
21
|
+
assert_equal [{ name: '!serialize.active_model_serializers', serializer: 'ActiveModel::DefaultSerializer' }], @events
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_instruments_serializer
|
25
|
+
profile = Profile.new(name: 'Name 1', description: 'Description 1', comments: 'Comments 1')
|
26
|
+
serializer = ProfileSerializer.new(profile)
|
27
|
+
|
28
|
+
serializer.as_json
|
29
|
+
|
30
|
+
assert_equal [{ name: '!serialize.active_model_serializers', serializer: 'ProfileSerializer' }], @events
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_instruments_array_serializer
|
34
|
+
profiles = [
|
35
|
+
Profile.new(name: 'Name 1', description: 'Description 1', comments: 'Comments 1'),
|
36
|
+
Profile.new(name: 'Name 2', description: 'Description 2', comments: 'Comments 2')
|
37
|
+
]
|
38
|
+
serializer = ArraySerializer.new(profiles)
|
39
|
+
|
40
|
+
serializer.as_json
|
41
|
+
|
42
|
+
assert_equal [
|
43
|
+
{ name: '!serialize.active_model_serializers', serializer: 'ProfileSerializer' },
|
44
|
+
{ name: '!serialize.active_model_serializers', serializer: 'ProfileSerializer' },
|
45
|
+
{ name: '!serialize.active_model_serializers', serializer: 'ActiveModel::ArraySerializer' }
|
46
|
+
], @events
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
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.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- José Valim
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2017-01
|
13
|
+
date: 2017-05-01 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: activemodel
|
@@ -26,6 +26,20 @@ dependencies:
|
|
26
26
|
- - ">="
|
27
27
|
- !ruby/object:Gem::Version
|
28
28
|
version: '3.2'
|
29
|
+
- !ruby/object:Gem::Dependency
|
30
|
+
name: concurrent-ruby
|
31
|
+
requirement: !ruby/object:Gem::Requirement
|
32
|
+
requirements:
|
33
|
+
- - "~>"
|
34
|
+
- !ruby/object:Gem::Version
|
35
|
+
version: '1.0'
|
36
|
+
type: :runtime
|
37
|
+
prerelease: false
|
38
|
+
version_requirements: !ruby/object:Gem::Requirement
|
39
|
+
requirements:
|
40
|
+
- - "~>"
|
41
|
+
- !ruby/object:Gem::Version
|
42
|
+
version: '1.0'
|
29
43
|
- !ruby/object:Gem::Dependency
|
30
44
|
name: rails
|
31
45
|
requirement: !ruby/object:Gem::Requirement
|
@@ -77,7 +91,12 @@ files:
|
|
77
91
|
- lib/active_model_serializers.rb
|
78
92
|
- lib/bulk_cache_fetcher.rb
|
79
93
|
- test/action_controller/http_cache_test.rb
|
94
|
+
- test/action_controller/regression_test.rb
|
95
|
+
- test/benchmark/app.rb
|
96
|
+
- test/benchmark/benchmarking_support.rb
|
97
|
+
- test/benchmark/bm_active_record.rb
|
80
98
|
- test/benchmark/bm_rails_cache.rb
|
99
|
+
- test/benchmark/setup.rb
|
81
100
|
- test/benchmark/tmp/miniprofiler/mp_timers_16x1i2wkkt8b8zybbfbx
|
82
101
|
- test/benchmark/tmp/miniprofiler/mp_timers_3aa299ezxdqvog6sfjzr
|
83
102
|
- test/benchmark/tmp/miniprofiler/mp_timers_3f0bdfx4nib4hxfb5lmq
|
@@ -145,6 +164,7 @@ files:
|
|
145
164
|
- test/unit/active_model/serializer/root_test.rb
|
146
165
|
- test/unit/active_model/serializer/scope_test.rb
|
147
166
|
- test/unit/active_model/serializer/url_helpers_test.rb
|
167
|
+
- test/unit/active_model/serilizable_test.rb
|
148
168
|
homepage: https://github.com/rails-api/active_model_serializers
|
149
169
|
licenses:
|
150
170
|
- MIT
|
@@ -172,7 +192,12 @@ summary: Bringing consistency and object orientation to model serialization. Wor
|
|
172
192
|
great for client-side MVC frameworks!
|
173
193
|
test_files:
|
174
194
|
- test/action_controller/http_cache_test.rb
|
195
|
+
- test/action_controller/regression_test.rb
|
196
|
+
- test/benchmark/app.rb
|
197
|
+
- test/benchmark/benchmarking_support.rb
|
198
|
+
- test/benchmark/bm_active_record.rb
|
175
199
|
- test/benchmark/bm_rails_cache.rb
|
200
|
+
- test/benchmark/setup.rb
|
176
201
|
- test/benchmark/tmp/miniprofiler/mp_timers_16x1i2wkkt8b8zybbfbx
|
177
202
|
- test/benchmark/tmp/miniprofiler/mp_timers_3aa299ezxdqvog6sfjzr
|
178
203
|
- test/benchmark/tmp/miniprofiler/mp_timers_3f0bdfx4nib4hxfb5lmq
|
@@ -240,3 +265,4 @@ test_files:
|
|
240
265
|
- test/unit/active_model/serializer/root_test.rb
|
241
266
|
- test/unit/active_model/serializer/scope_test.rb
|
242
267
|
- test/unit/active_model/serializer/url_helpers_test.rb
|
268
|
+
- test/unit/active_model/serilizable_test.rb
|