active_model_serializers 0.9.8 → 0.10.15

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.
Files changed (143) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +646 -59
  3. data/MIT-LICENSE +3 -2
  4. data/README.md +194 -846
  5. data/lib/action_controller/serialization.rb +35 -66
  6. data/lib/active_model/serializable_resource.rb +13 -0
  7. data/lib/active_model/serializer/adapter/attributes.rb +17 -0
  8. data/lib/active_model/serializer/adapter/base.rb +20 -0
  9. data/lib/active_model/serializer/adapter/json.rb +17 -0
  10. data/lib/active_model/serializer/adapter/json_api.rb +17 -0
  11. data/lib/active_model/serializer/adapter/null.rb +17 -0
  12. data/lib/active_model/serializer/adapter.rb +26 -0
  13. data/lib/active_model/serializer/array_serializer.rb +14 -0
  14. data/lib/active_model/serializer/association.rb +55 -40
  15. data/lib/active_model/serializer/attribute.rb +27 -0
  16. data/lib/active_model/serializer/belongs_to_reflection.rb +13 -0
  17. data/lib/active_model/serializer/collection_serializer.rb +99 -0
  18. data/lib/active_model/serializer/concerns/caching.rb +305 -0
  19. data/lib/active_model/serializer/error_serializer.rb +16 -0
  20. data/lib/active_model/serializer/errors_serializer.rb +34 -0
  21. data/lib/active_model/serializer/field.rb +92 -0
  22. data/lib/active_model/serializer/fieldset.rb +33 -0
  23. data/lib/active_model/serializer/has_many_reflection.rb +12 -0
  24. data/lib/active_model/serializer/has_one_reflection.rb +9 -0
  25. data/lib/active_model/serializer/lazy_association.rb +99 -0
  26. data/lib/active_model/serializer/link.rb +23 -0
  27. data/lib/active_model/serializer/lint.rb +152 -0
  28. data/lib/active_model/serializer/null.rb +19 -0
  29. data/lib/active_model/serializer/reflection.rb +212 -0
  30. data/lib/active_model/serializer/version.rb +3 -1
  31. data/lib/active_model/serializer.rb +363 -254
  32. data/lib/active_model_serializers/adapter/attributes.rb +36 -0
  33. data/lib/active_model_serializers/adapter/base.rb +85 -0
  34. data/lib/active_model_serializers/adapter/json.rb +23 -0
  35. data/lib/active_model_serializers/adapter/json_api/deserialization.rb +215 -0
  36. data/lib/active_model_serializers/adapter/json_api/error.rb +98 -0
  37. data/lib/active_model_serializers/adapter/json_api/jsonapi.rb +51 -0
  38. data/lib/active_model_serializers/adapter/json_api/link.rb +85 -0
  39. data/lib/active_model_serializers/adapter/json_api/meta.rb +39 -0
  40. data/lib/active_model_serializers/adapter/json_api/pagination_links.rb +94 -0
  41. data/lib/active_model_serializers/adapter/json_api/relationship.rb +106 -0
  42. data/lib/active_model_serializers/adapter/json_api/resource_identifier.rb +68 -0
  43. data/lib/active_model_serializers/adapter/json_api.rb +535 -0
  44. data/lib/active_model_serializers/adapter/null.rb +11 -0
  45. data/lib/active_model_serializers/adapter.rb +100 -0
  46. data/lib/active_model_serializers/callbacks.rb +57 -0
  47. data/lib/active_model_serializers/deprecate.rb +56 -0
  48. data/lib/active_model_serializers/deserialization.rb +17 -0
  49. data/lib/active_model_serializers/json_pointer.rb +16 -0
  50. data/lib/active_model_serializers/logging.rb +124 -0
  51. data/lib/active_model_serializers/lookup_chain.rb +82 -0
  52. data/lib/active_model_serializers/model.rb +132 -0
  53. data/lib/active_model_serializers/railtie.rb +62 -0
  54. data/lib/active_model_serializers/register_jsonapi_renderer.rb +80 -0
  55. data/lib/active_model_serializers/serializable_resource.rb +84 -0
  56. data/lib/active_model_serializers/serialization_context.rb +41 -0
  57. data/lib/active_model_serializers/test/schema.rb +140 -0
  58. data/lib/active_model_serializers/test/serializer.rb +127 -0
  59. data/lib/active_model_serializers/test.rb +9 -0
  60. data/lib/active_model_serializers.rb +60 -17
  61. data/lib/generators/rails/USAGE +6 -0
  62. data/lib/{active_model/serializer/generators → generators/rails}/resource_override.rb +3 -4
  63. data/lib/{active_model/serializer/generators/serializer → generators/rails}/serializer_generator.rb +6 -5
  64. data/lib/grape/active_model_serializers.rb +18 -0
  65. data/lib/grape/formatters/active_model_serializers.rb +34 -0
  66. data/lib/grape/helpers/active_model_serializers.rb +19 -0
  67. data/lib/tasks/rubocop.rake +60 -0
  68. metadata +249 -157
  69. data/CONTRIBUTING.md +0 -20
  70. data/DESIGN.textile +0 -586
  71. data/lib/action_controller/serialization_test_case.rb +0 -79
  72. data/lib/active_model/array_serializer.rb +0 -68
  73. data/lib/active_model/default_serializer.rb +0 -28
  74. data/lib/active_model/serializable/utils.rb +0 -16
  75. data/lib/active_model/serializable.rb +0 -59
  76. data/lib/active_model/serializer/association/has_many.rb +0 -39
  77. data/lib/active_model/serializer/association/has_one.rb +0 -25
  78. data/lib/active_model/serializer/config.rb +0 -31
  79. data/lib/active_model/serializer/generators/serializer/USAGE +0 -9
  80. data/lib/active_model/serializer/generators/serializer/scaffold_controller_generator.rb +0 -14
  81. data/lib/active_model/serializer/generators/serializer/templates/controller.rb +0 -93
  82. data/lib/active_model/serializer/railtie.rb +0 -22
  83. data/lib/active_model/serializer_support.rb +0 -5
  84. data/lib/active_model_serializers/model/caching.rb +0 -25
  85. data/test/benchmark/app.rb +0 -60
  86. data/test/benchmark/benchmarking_support.rb +0 -67
  87. data/test/benchmark/bm_active_record.rb +0 -41
  88. data/test/benchmark/setup.rb +0 -75
  89. data/test/benchmark/tmp/miniprofiler/mp_timers_6eqewtfgrhitvq5gqm25 +0 -0
  90. data/test/benchmark/tmp/miniprofiler/mp_timers_8083sx03hu72pxz1a4d0 +0 -0
  91. data/test/benchmark/tmp/miniprofiler/mp_timers_fyz2gsml4z0ph9kpoy1c +0 -0
  92. data/test/benchmark/tmp/miniprofiler/mp_timers_hjry5rc32imd42oxoi48 +0 -0
  93. data/test/benchmark/tmp/miniprofiler/mp_timers_m8fpoz2cvt3g9agz0bs3 +0 -0
  94. data/test/benchmark/tmp/miniprofiler/mp_timers_p92m2drnj1i568u3sta0 +0 -0
  95. data/test/benchmark/tmp/miniprofiler/mp_timers_qg52tpca3uesdfguee9i +0 -0
  96. data/test/benchmark/tmp/miniprofiler/mp_timers_s15t1a6mvxe0z7vjv790 +0 -0
  97. data/test/benchmark/tmp/miniprofiler/mp_timers_x8kal3d17nfds6vp4kcj +0 -0
  98. data/test/benchmark/tmp/miniprofiler/mp_views_127.0.0.1 +0 -0
  99. data/test/fixtures/active_record.rb +0 -96
  100. data/test/fixtures/poro.rb +0 -223
  101. data/test/fixtures/template.html.erb +0 -1
  102. data/test/integration/action_controller/namespaced_serialization_test.rb +0 -105
  103. data/test/integration/action_controller/serialization_test.rb +0 -287
  104. data/test/integration/action_controller/serialization_test_case_test.rb +0 -71
  105. data/test/integration/active_record/active_record_test.rb +0 -94
  106. data/test/integration/generators/resource_generator_test.rb +0 -26
  107. data/test/integration/generators/scaffold_controller_generator_test.rb +0 -64
  108. data/test/integration/generators/serializer_generator_test.rb +0 -41
  109. data/test/test_app.rb +0 -14
  110. data/test/test_helper.rb +0 -24
  111. data/test/tmp/app/assets/javascripts/accounts.js +0 -2
  112. data/test/tmp/app/assets/stylesheets/accounts.css +0 -4
  113. data/test/tmp/app/controllers/accounts_controller.rb +0 -2
  114. data/test/tmp/app/helpers/accounts_helper.rb +0 -2
  115. data/test/tmp/app/serializers/account_serializer.rb +0 -3
  116. data/test/tmp/config/routes.rb +0 -1
  117. data/test/unit/active_model/array_serializer/except_test.rb +0 -18
  118. data/test/unit/active_model/array_serializer/key_format_test.rb +0 -18
  119. data/test/unit/active_model/array_serializer/meta_test.rb +0 -53
  120. data/test/unit/active_model/array_serializer/only_test.rb +0 -18
  121. data/test/unit/active_model/array_serializer/options_test.rb +0 -16
  122. data/test/unit/active_model/array_serializer/root_test.rb +0 -102
  123. data/test/unit/active_model/array_serializer/scope_test.rb +0 -24
  124. data/test/unit/active_model/array_serializer/serialization_test.rb +0 -216
  125. data/test/unit/active_model/default_serializer_test.rb +0 -13
  126. data/test/unit/active_model/serializer/associations/build_serializer_test.rb +0 -36
  127. data/test/unit/active_model/serializer/associations_test.rb +0 -49
  128. data/test/unit/active_model/serializer/attributes_test.rb +0 -57
  129. data/test/unit/active_model/serializer/config_test.rb +0 -91
  130. data/test/unit/active_model/serializer/filter_test.rb +0 -69
  131. data/test/unit/active_model/serializer/has_many_polymorphic_test.rb +0 -189
  132. data/test/unit/active_model/serializer/has_many_test.rb +0 -265
  133. data/test/unit/active_model/serializer/has_one_and_has_many_test.rb +0 -27
  134. data/test/unit/active_model/serializer/has_one_polymorphic_test.rb +0 -196
  135. data/test/unit/active_model/serializer/has_one_test.rb +0 -253
  136. data/test/unit/active_model/serializer/key_format_test.rb +0 -25
  137. data/test/unit/active_model/serializer/meta_test.rb +0 -39
  138. data/test/unit/active_model/serializer/options_test.rb +0 -42
  139. data/test/unit/active_model/serializer/root_test.rb +0 -117
  140. data/test/unit/active_model/serializer/scope_test.rb +0 -49
  141. data/test/unit/active_model/serializer/url_helpers_test.rb +0 -35
  142. data/test/unit/active_model/serilizable_test.rb +0 -50
  143. /data/lib/{active_model/serializer/generators/serializer/templates/serializer.rb → generators/rails/templates/serializer.rb.erb} +0 -0
@@ -1,68 +0,0 @@
1
- require 'active_model/default_serializer'
2
- require 'active_model/serializable'
3
-
4
- module ActiveModel
5
- class ArraySerializer
6
- include Serializable
7
-
8
- class << self
9
- attr_accessor :_root
10
- alias root _root=
11
- alias root= _root=
12
- end
13
-
14
- def initialize(object, options={})
15
- @object = object
16
- @scope = options[:scope]
17
- @root = options.fetch(:root, self.class._root)
18
- @polymorphic = options.fetch(:polymorphic, false)
19
- @meta_key = options[:meta_key] || :meta
20
- @meta = options[@meta_key]
21
- @each_serializer = options[:each_serializer]
22
- @resource_name = options[:resource_name]
23
- @only = options[:only] ? Array(options[:only]) : nil
24
- @except = options[:except] ? Array(options[:except]) : nil
25
- @context = options[:context]
26
- @namespace = options[:namespace]
27
- @key_format = options[:key_format] || options[:each_serializer].try(:key_format)
28
- end
29
- attr_accessor :object, :scope, :root, :meta_key, :meta, :key_format, :context
30
-
31
- def json_key
32
- key = root.nil? ? @resource_name : root
33
-
34
- key_format == :lower_camel && key.present? ? key.camelize(:lower) : key
35
- end
36
-
37
- def serializer_for(item)
38
- serializer_class = @each_serializer || Serializer.serializer_for(item, namespace: @namespace) || DefaultSerializer
39
- serializer_class.new(item, scope: scope, key_format: key_format, context: @context, only: @only, except: @except, polymorphic: @polymorphic, namespace: @namespace)
40
- end
41
-
42
- def serializable_object(options={})
43
- @object.map do |item|
44
- serializer_for(item).serializable_object_with_notification(options)
45
- end
46
- end
47
- alias_method :serializable_array, :serializable_object
48
-
49
- def embedded_in_root_associations
50
- @object.each_with_object({}) do |item, hash|
51
- serializer_for(item).embedded_in_root_associations.each_pair do |type, objects|
52
- next if !objects || objects.flatten.empty?
53
-
54
- if hash.has_key?(type)
55
- case hash[type] when Hash
56
- hash[type].deep_merge!(objects){ |key, old, new| (Array(old) + Array(new)).uniq }
57
- else
58
- hash[type].concat(objects).uniq!
59
- end
60
- else
61
- hash[type] = objects
62
- end
63
- end
64
- end
65
- end
66
-
67
- end
68
- end
@@ -1,28 +0,0 @@
1
- require 'active_model/serializable'
2
-
3
- module ActiveModel
4
- # DefaultSerializer
5
- #
6
- # Provides a constant interface for all items
7
- class DefaultSerializer
8
- include ActiveModel::Serializable
9
-
10
- attr_reader :object
11
-
12
- def initialize(object, options={})
13
- @object = object
14
- @wrap_in_array = options[:_wrap_in_array]
15
- end
16
-
17
- def as_json(options={})
18
- instrument do
19
- return [] if @object.nil? && @wrap_in_array
20
- hash = @object.as_json
21
- @wrap_in_array ? [hash] : hash
22
- end
23
- end
24
-
25
- alias serializable_hash as_json
26
- alias serializable_object as_json
27
- end
28
- end
@@ -1,16 +0,0 @@
1
- module ActiveModel
2
- module Serializable
3
- module Utils
4
- extend self
5
-
6
- def _const_get(const)
7
- begin
8
- method = RUBY_VERSION >= '2.0' ? :const_get : :qualified_const_get
9
- Object.send method, const
10
- rescue NameError
11
- const.safe_constantize
12
- end
13
- end
14
- end
15
- end
16
- end
@@ -1,59 +0,0 @@
1
- require 'active_model/serializable/utils'
2
-
3
- module ActiveModel
4
- module Serializable
5
- INSTRUMENTATION_KEY = '!serialize.active_model_serializers'.freeze
6
-
7
- def self.included(base)
8
- base.extend Utils
9
- end
10
-
11
- def as_json(options={})
12
- instrument do
13
- if root = options.fetch(:root, json_key)
14
- hash = { root => serializable_object(options) }
15
- hash.merge!(serializable_data)
16
- hash
17
- else
18
- serializable_object(options)
19
- end
20
- end
21
- end
22
-
23
- def serializable_object_with_notification(options={})
24
- instrument { serializable_object(options) }
25
- end
26
-
27
- def serializable_data
28
- embedded_in_root_associations.tap do |hash|
29
- if respond_to?(:meta) && meta
30
- hash[meta_key] = meta
31
- end
32
- end
33
- end
34
-
35
- def namespace
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
41
- end
42
-
43
- def embedded_in_root_associations
44
- {}
45
- end
46
-
47
- private
48
-
49
- def get_namespace
50
- modules = self.class.name.split('::')
51
- modules[0..-2].join('::') if modules.size > 1
52
- end
53
-
54
- def instrument(&block)
55
- payload = { serializer: self.class.name }
56
- ActiveSupport::Notifications.instrument(INSTRUMENTATION_KEY, payload, &block)
57
- end
58
- end
59
- end
@@ -1,39 +0,0 @@
1
- module ActiveModel
2
- class Serializer
3
- class Association
4
- class HasMany < Association
5
- def initialize(name, *args)
6
- super
7
- @root_key = @embedded_key.to_s
8
- @key ||= case CONFIG.default_key_type
9
- when :name then name.to_s.pluralize
10
- else "#{name.to_s.singularize}_ids"
11
- end
12
- end
13
-
14
- def serializer_class(object, _)
15
- if use_array_serializer?
16
- ArraySerializer
17
- else
18
- serializer_from_options
19
- end
20
- end
21
-
22
- def options
23
- if use_array_serializer?
24
- { each_serializer: serializer_from_options }.merge! super
25
- else
26
- super
27
- end
28
- end
29
-
30
- private
31
-
32
- def use_array_serializer?
33
- !serializer_from_options ||
34
- serializer_from_options && !(serializer_from_options <= ArraySerializer)
35
- end
36
- end
37
- end
38
- end
39
- end
@@ -1,25 +0,0 @@
1
- module ActiveModel
2
- class Serializer
3
- class Association
4
- class HasOne < Association
5
- def initialize(name, *args)
6
- super
7
- @root_key = @embedded_key.to_s.pluralize
8
- @key ||= case CONFIG.default_key_type
9
- when :name then name.to_s.singularize
10
- else "#{name}_id"
11
- end
12
- end
13
-
14
- def serializer_class(object, options = {})
15
- (serializer_from_options unless object.nil?) || serializer_from_object(object, options) || default_serializer
16
- end
17
-
18
- def build_serializer(object, options = {})
19
- options[:_wrap_in_array] = embed_in_root?
20
- super
21
- end
22
- end
23
- end
24
- end
25
- end
@@ -1,31 +0,0 @@
1
- module ActiveModel
2
- class Serializer
3
- class Config
4
- def initialize(data = {})
5
- @data = data
6
- end
7
-
8
- def each(&block)
9
- @data.each(&block)
10
- end
11
-
12
- def clear
13
- @data.clear
14
- end
15
-
16
- def method_missing(name, *args)
17
- name = name.to_s
18
- return @data[name] if @data.include?(name)
19
- match = name.match(/\A(.*?)([?=]?)\Z/)
20
- case match[2]
21
- when "="
22
- @data[match[1]] = args.first
23
- when "?"
24
- !!@data[match[1]]
25
- end
26
- end
27
- end
28
-
29
- CONFIG = Config.new('embed' => :objects) # :nodoc:
30
- end
31
- end
@@ -1,9 +0,0 @@
1
- Description:
2
- Generates a serializer for the given resource with tests.
3
-
4
- Example:
5
- `rails generate serializer Account name created_at`
6
-
7
- For TestUnit it creates:
8
- Serializer: app/serializers/account_serializer.rb
9
- TestUnit: test/unit/account_serializer_test.rb
@@ -1,14 +0,0 @@
1
- require 'rails/generators'
2
- require 'rails/generators/rails/scaffold_controller/scaffold_controller_generator'
3
-
4
- module Rails
5
- module Generators
6
- class ScaffoldControllerGenerator
7
- if Rails::VERSION::MAJOR >= 4
8
- source_root File.expand_path('../templates', __FILE__)
9
-
10
- hook_for :serializer, default: true, type: :boolean
11
- end
12
- end
13
- end
14
- end
@@ -1,93 +0,0 @@
1
- <% if namespaced? -%>
2
- require_dependency "<%= namespaced_file_path %>/application_controller"
3
-
4
- <% end -%>
5
- <% module_namespacing do -%>
6
- class <%= controller_class_name %>Controller < ApplicationController
7
- before_action :set_<%= singular_table_name %>, only: [:show, :edit, :update, :destroy]
8
-
9
- # GET <%= route_url %>
10
- # GET <%= route_url %>.json
11
- def index
12
- @<%= plural_table_name %> = <%= orm_class.all(class_name) %>
13
-
14
- respond_to do |format|
15
- format.html # index.html.erb
16
- format.json { render json: <%= "@#{plural_table_name}" %> }
17
- end
18
- end
19
-
20
- # GET <%= route_url %>/1
21
- # GET <%= route_url %>/1.json
22
- def show
23
- respond_to do |format|
24
- format.html # show.html.erb
25
- format.json { render json: <%= "@#{singular_table_name}" %> }
26
- end
27
- end
28
-
29
- # GET <%= route_url %>/new
30
- def new
31
- @<%= singular_table_name %> = <%= orm_class.build(class_name) %>
32
- end
33
-
34
- # GET <%= route_url %>/1/edit
35
- def edit
36
- end
37
-
38
- # POST <%= route_url %>
39
- # POST <%= route_url %>.json
40
- def create
41
- @<%= singular_table_name %> = <%= orm_class.build(class_name, "#{singular_table_name}_params") %>
42
-
43
- respond_to do |format|
44
- if @<%= orm_instance.save %>
45
- format.html { redirect_to @<%= singular_table_name %>, notice: <%= "'#{human_name} was successfully created.'" %> }
46
- format.json { render json: <%= "@#{singular_table_name}" %>, status: :created }
47
- else
48
- format.html { render action: 'new' }
49
- format.json { render json: <%= "@#{orm_instance.errors}" %>, status: :unprocessable_entity }
50
- end
51
- end
52
- end
53
-
54
- # PATCH/PUT <%= route_url %>/1
55
- # PATCH/PUT <%= route_url %>/1.json
56
- def update
57
- respond_to do |format|
58
- if @<%= orm_instance.update("#{singular_table_name}_params") %>
59
- format.html { redirect_to @<%= singular_table_name %>, notice: <%= "'#{human_name} was successfully updated.'" %> }
60
- format.json { head :no_content }
61
- else
62
- format.html { render action: 'edit' }
63
- format.json { render json: <%= "@#{orm_instance.errors}" %>, status: :unprocessable_entity }
64
- end
65
- end
66
- end
67
-
68
- # DELETE <%= route_url %>/1
69
- # DELETE <%= route_url %>/1.json
70
- def destroy
71
- @<%= orm_instance.destroy %>
72
- respond_to do |format|
73
- format.html { redirect_to <%= index_helper %>_url }
74
- format.json { head :no_content }
75
- end
76
- end
77
-
78
- private
79
- # Use callbacks to share common setup or constraints between actions.
80
- def set_<%= singular_table_name %>
81
- @<%= singular_table_name %> = <%= orm_class.find(class_name, "params[:id]") %>
82
- end
83
-
84
- # Never trust parameters from the scary internet, only allow the white list through.
85
- def <%= "#{singular_table_name}_params" %>
86
- <%- if attributes_names.empty? -%>
87
- params[<%= ":#{singular_table_name}" %>]
88
- <%- else -%>
89
- params.require(<%= ":#{singular_table_name}" %>).permit(<%= attributes_names.map { |name| ":#{name}" }.join(', ') %>)
90
- <%- end -%>
91
- end
92
- end
93
- <% end -%>
@@ -1,22 +0,0 @@
1
- module ActiveModel
2
- class Railtie < Rails::Railtie
3
- initializer 'generators' do |app|
4
- app.load_generators
5
- require 'active_model/serializer/generators/serializer/serializer_generator'
6
- require 'active_model/serializer/generators/serializer/scaffold_controller_generator'
7
- require 'active_model/serializer/generators/resource_override'
8
- end
9
-
10
- initializer 'include_routes.active_model_serializer' do |app|
11
- ActiveSupport.on_load(:active_model_serializers) do
12
- include app.routes.url_helpers
13
- end
14
- end
15
-
16
- config.to_prepare do
17
- ActiveModel::Serializer.serializers_cache.clear
18
- end
19
- end
20
- end
21
-
22
- ActiveSupport.run_load_hooks(:active_model_serializers, ActiveModel::Serializer)
@@ -1,5 +0,0 @@
1
- module ActiveModel
2
- module SerializerSupport
3
- alias read_attribute_for_serialization send
4
- end
5
- end
@@ -1,25 +0,0 @@
1
- module ActiveModelSerializers
2
- class Model
3
- module Caching
4
- extend ActiveSupport::Concern
5
-
6
- included do
7
- attr_writer :updated_at
8
- attributes :id
9
- end
10
-
11
- # Defaults to the downcased model name and updated_at
12
- def cache_key
13
- ActiveSupport::Cache.expand_cache_key([
14
- self.class.model_name.name.downcase,
15
- "#{id}-#{updated_at.strftime('%Y%m%d%H%M%S%9N')}"
16
- ].compact)
17
- end
18
-
19
- # Defaults to the time the serializer file was modified.
20
- def updated_at
21
- defined?(@updated_at) ? @updated_at : File.mtime(__FILE__)
22
- end
23
- end
24
- end
25
- end
@@ -1,60 +0,0 @@
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
-
@@ -1,67 +0,0 @@
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
@@ -1,41 +0,0 @@
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
@@ -1,75 +0,0 @@
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)