active_model_serializers 0.10.2 → 0.10.3

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 (80) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +8 -1
  3. data/CHANGELOG.md +45 -3
  4. data/CODE_OF_CONDUCT.md +74 -0
  5. data/Gemfile +4 -1
  6. data/README.md +5 -2
  7. data/active_model_serializers.gemspec +2 -2
  8. data/docs/ARCHITECTURE.md +6 -7
  9. data/docs/README.md +2 -0
  10. data/docs/general/caching.md +7 -1
  11. data/docs/general/configuration_options.md +64 -0
  12. data/docs/general/rendering.md +35 -1
  13. data/docs/general/serializers.md +35 -5
  14. data/docs/howto/add_pagination_links.md +2 -2
  15. data/docs/howto/add_relationship_links.md +137 -0
  16. data/docs/howto/add_root_key.md +4 -0
  17. data/docs/howto/grape_integration.md +42 -0
  18. data/docs/howto/outside_controller_use.md +9 -2
  19. data/docs/howto/passing_arbitrary_options.md +2 -2
  20. data/docs/howto/test.md +2 -0
  21. data/docs/howto/upgrade_from_0_8_to_0_10.md +265 -0
  22. data/docs/integrations/ember-and-json-api.md +41 -24
  23. data/lib/action_controller/serialization.rb +9 -0
  24. data/lib/active_model/serializer.rb +19 -22
  25. data/lib/active_model/serializer/association.rb +19 -4
  26. data/lib/active_model/serializer/collection_serializer.rb +8 -5
  27. data/lib/active_model/serializer/{associations.rb → concerns/associations.rb} +8 -5
  28. data/lib/active_model/serializer/{attributes.rb → concerns/attributes.rb} +0 -0
  29. data/lib/active_model/serializer/{caching.rb → concerns/caching.rb} +5 -1
  30. data/lib/active_model/serializer/{configuration.rb → concerns/configuration.rb} +24 -1
  31. data/lib/active_model/serializer/{links.rb → concerns/links.rb} +0 -0
  32. data/lib/active_model/serializer/{meta.rb → concerns/meta.rb} +0 -0
  33. data/lib/active_model/serializer/{type.rb → concerns/type.rb} +0 -0
  34. data/lib/active_model/serializer/reflection.rb +37 -21
  35. data/lib/active_model/serializer/version.rb +1 -1
  36. data/lib/active_model_serializers.rb +1 -0
  37. data/lib/active_model_serializers/adapter/attributes.rb +3 -1
  38. data/lib/active_model_serializers/adapter/json_api.rb +15 -22
  39. data/lib/active_model_serializers/adapter/json_api/relationship.rb +30 -19
  40. data/lib/active_model_serializers/adapter/json_api/resource_identifier.rb +23 -9
  41. data/lib/active_model_serializers/key_transform.rb +4 -0
  42. data/lib/active_model_serializers/lookup_chain.rb +80 -0
  43. data/lib/active_model_serializers/model.rb +1 -1
  44. data/lib/active_model_serializers/serializable_resource.rb +6 -5
  45. data/lib/generators/rails/serializer_generator.rb +1 -1
  46. data/test/action_controller/json_api/fields_test.rb +57 -0
  47. data/test/action_controller/json_api/transform_test.rb +3 -3
  48. data/test/action_controller/lookup_proc_test.rb +49 -0
  49. data/test/action_controller/namespace_lookup_test.rb +226 -0
  50. data/test/active_model_serializers/key_transform_test.rb +32 -0
  51. data/test/active_model_serializers/model_test.rb +11 -0
  52. data/test/adapter/attributes_test.rb +43 -0
  53. data/test/adapter/json/transform_test.rb +1 -1
  54. data/test/adapter/json_api/fields_test.rb +4 -3
  55. data/test/adapter/json_api/has_many_test.rb +21 -0
  56. data/test/adapter/json_api/include_data_if_sideloaded_test.rb +166 -0
  57. data/test/adapter/json_api/linked_test.rb +24 -6
  58. data/test/adapter/json_api/links_test.rb +1 -1
  59. data/test/adapter/json_api/pagination_links_test.rb +17 -2
  60. data/test/adapter/json_api/relationship_test.rb +309 -73
  61. data/test/adapter/json_api/resource_identifier_test.rb +20 -0
  62. data/test/adapter/json_api/transform_test.rb +4 -3
  63. data/test/benchmark/benchmarking_support.rb +1 -1
  64. data/test/benchmark/bm_active_record.rb +81 -0
  65. data/test/benchmark/bm_adapter.rb +38 -0
  66. data/test/benchmark/bm_caching.rb +1 -1
  67. data/test/benchmark/bm_lookup_chain.rb +83 -0
  68. data/test/cache_test.rb +42 -4
  69. data/test/collection_serializer_test.rb +1 -1
  70. data/test/fixtures/poro.rb +44 -41
  71. data/test/generators/serializer_generator_test.rb +22 -5
  72. data/test/serializers/association_macros_test.rb +3 -2
  73. data/test/serializers/associations_test.rb +97 -22
  74. data/test/serializers/attribute_test.rb +1 -1
  75. data/test/serializers/serializer_for_test.rb +3 -3
  76. data/test/serializers/serializer_for_with_namespace_test.rb +87 -0
  77. data/test/support/serialization_testing.rb +16 -0
  78. data/test/test_helper.rb +1 -0
  79. metadata +35 -14
  80. data/test/adapter/json_api/relationships_test.rb +0 -204
@@ -39,6 +39,26 @@ module ActiveModelSerializers
39
39
  test_type_inflection(AuthorSerializer, 'authors', :plural)
40
40
  end
41
41
 
42
+ def test_type_with_namespace
43
+ Object.const_set(:Admin, Module.new)
44
+ model = Class.new(::Model)
45
+ Admin.const_set(:PowerUser, model)
46
+ serializer = Class.new(ActiveModel::Serializer)
47
+ Admin.const_set(:PowerUserSerializer, serializer)
48
+ with_namespace_separator '--' do
49
+ admin_user = Admin::PowerUser.new
50
+ serializer = Admin::PowerUserSerializer.new(admin_user)
51
+ expected = {
52
+ id: admin_user.id,
53
+ type: 'admin--power-users'
54
+ }
55
+
56
+ identifier = ResourceIdentifier.new(serializer, {})
57
+ actual = identifier.as_json
58
+ assert_equal(expected, actual)
59
+ end
60
+ end
61
+
42
62
  def test_id_defined_on_object
43
63
  test_id(AuthorSerializer, @model.id.to_s)
44
64
  end
@@ -4,7 +4,10 @@ module ActiveModelSerializers
4
4
  module Adapter
5
5
  class JsonApi
6
6
  class KeyCaseTest < ActiveSupport::TestCase
7
- Post = Class.new(::Model)
7
+ class Post < ::Model; end
8
+ class Author < ::Model; end
9
+ class Comment < ::Model; end
10
+
8
11
  class PostSerializer < ActiveModel::Serializer
9
12
  type 'posts'
10
13
  attributes :title, :body, :publish_at
@@ -23,13 +26,11 @@ module ActiveModelSerializers
23
26
  end
24
27
  end
25
28
 
26
- Author = Class.new(::Model)
27
29
  class AuthorSerializer < ActiveModel::Serializer
28
30
  type 'authors'
29
31
  attributes :first_name, :last_name
30
32
  end
31
33
 
32
- Comment = Class.new(::Model)
33
34
  class CommentSerializer < ActiveModel::Serializer
34
35
  type 'comments'
35
36
  attributes :body
@@ -36,7 +36,7 @@ module Benchmark
36
36
  version: ::ActiveModel::Serializer::VERSION.to_s,
37
37
  rails_version: ::Rails.version.to_s,
38
38
  iterations_per_second: entry.ips,
39
- iterations_per_second_standard_deviation: entry.stddev_percentage,
39
+ iterations_per_second_standard_deviation: entry.error_percentage,
40
40
  total_allocated_objects_per_iteration: count_total_allocated_objects(&block)
41
41
  }.to_json
42
42
 
@@ -0,0 +1,81 @@
1
+ require_relative './benchmarking_support'
2
+ require_relative './app'
3
+
4
+ time = 10
5
+ disable_gc = true
6
+
7
+ # This is to disable any key transform effects that may impact performance
8
+ ActiveModelSerializers.config.key_transform = :unaltered
9
+
10
+ ###########################################
11
+ # Setup active record models
12
+ ##########################################
13
+ require 'active_record'
14
+ require 'sqlite3'
15
+
16
+ # For debugging SQL output
17
+ # ActiveRecord::Base.logger = Logger.new(STDERR)
18
+
19
+ # Change the following to reflect your database settings
20
+ ActiveRecord::Base.establish_connection(
21
+ adapter: 'sqlite3',
22
+ database: ':memory:'
23
+ )
24
+
25
+ # Don't show migration output when constructing fake db
26
+ ActiveRecord::Migration.verbose = false
27
+
28
+ ActiveRecord::Schema.define do
29
+ create_table :authors, force: true do |t|
30
+ t.string :name
31
+ end
32
+
33
+ create_table :posts, force: true do |t|
34
+ t.text :body
35
+ t.string :title
36
+ t.references :author
37
+ end
38
+
39
+ create_table :profiles, force: true do |t|
40
+ t.text :project_url
41
+ t.text :bio
42
+ t.date :birthday
43
+ t.references :author
44
+ end
45
+ end
46
+
47
+ class Author < ActiveRecord::Base
48
+ has_one :profile
49
+ has_many :posts
50
+ end
51
+
52
+ class Post < ActiveRecord::Base
53
+ belongs_to :author
54
+ end
55
+
56
+ class Profile < ActiveRecord::Base
57
+ belongs_to :author
58
+ end
59
+
60
+ # Build out the data to serialize
61
+ author = Author.create(name: 'Preston Sego')
62
+ Profile.create(project_url: 'https://github.com/NullVoxPopuli', author: author)
63
+ 50.times do
64
+ Post.create(
65
+ body: 'something about how password restrictions are evil, and less secure, and with the math to prove it.',
66
+ title: 'Your bank is does not know how to do security',
67
+ author: author
68
+ )
69
+ end
70
+
71
+ Benchmark.ams('AR: attributes', time: time, disable_gc: disable_gc) do
72
+ ActiveModelSerializers::SerializableResource.new(author, adapter: :attributes, include: 'profile,posts').serializable_hash
73
+ end
74
+
75
+ Benchmark.ams('AR: json', time: time, disable_gc: disable_gc) do
76
+ ActiveModelSerializers::SerializableResource.new(author, adapter: :json, include: 'profile,posts').serializable_hash
77
+ end
78
+
79
+ Benchmark.ams('AR: JSON API', time: time, disable_gc: disable_gc) do
80
+ ActiveModelSerializers::SerializableResource.new(author, adapter: :json_api, include: 'profile,posts').serializable_hash
81
+ end
@@ -0,0 +1,38 @@
1
+ require_relative './benchmarking_support'
2
+ require_relative './app'
3
+
4
+ time = 10
5
+ disable_gc = true
6
+ ActiveModelSerializers.config.key_transform = :unaltered
7
+ has_many_relationships = (0..60).map do |i|
8
+ HasManyRelationship.new(id: i, body: 'ZOMG A HAS MANY RELATIONSHIP')
9
+ end
10
+ has_one_relationship = HasOneRelationship.new(
11
+ id: 42,
12
+ first_name: 'Joao',
13
+ last_name: 'Moura'
14
+ )
15
+ primary_resource = PrimaryResource.new(
16
+ id: 1337,
17
+ title: 'New PrimaryResource',
18
+ virtual_attribute: nil,
19
+ body: 'Body',
20
+ has_many_relationships: has_many_relationships,
21
+ has_one_relationship: has_one_relationship
22
+ )
23
+ serializer = PrimaryResourceSerializer.new(primary_resource)
24
+
25
+ Benchmark.ams('attributes', time: time, disable_gc: disable_gc) do
26
+ attributes = ActiveModelSerializers::Adapter::Attributes.new(serializer)
27
+ attributes.as_json
28
+ end
29
+
30
+ Benchmark.ams('json_api', time: time, disable_gc: disable_gc) do
31
+ json_api = ActiveModelSerializers::Adapter::JsonApi.new(serializer)
32
+ json_api.as_json
33
+ end
34
+
35
+ Benchmark.ams('json', time: time, disable_gc: disable_gc) do
36
+ json = ActiveModelSerializers::Adapter::Json.new(serializer)
37
+ json.as_json
38
+ end
@@ -4,7 +4,7 @@ require_relative './app'
4
4
  # https://github.com/ruby-bench/ruby-bench-suite/blob/8ad567f7e43a044ae48c36833218423bb1e2bd9d/rails/benchmarks/actionpack_router.rb
5
5
  class ApiAssertion
6
6
  include Benchmark::ActiveModelSerializers::TestMethods
7
- BadRevisionError = Class.new(StandardError)
7
+ class BadRevisionError < StandardError; end
8
8
 
9
9
  def valid?
10
10
  caching = get_caching
@@ -0,0 +1,83 @@
1
+ require_relative './benchmarking_support'
2
+ require_relative './app'
3
+
4
+ time = 10
5
+ disable_gc = true
6
+ ActiveModelSerializers.config.key_transform = :unaltered
7
+
8
+ module AmsBench
9
+ module Api
10
+ module V1
11
+ class PrimaryResourceSerializer < ActiveModel::Serializer
12
+ attributes :title, :body
13
+
14
+ has_many :has_many_relationships
15
+ end
16
+
17
+ class HasManyRelationshipSerializer < ActiveModel::Serializer
18
+ attribute :body
19
+ end
20
+ end
21
+ end
22
+ class PrimaryResourceSerializer < ActiveModel::Serializer
23
+ attributes :title, :body
24
+
25
+ has_many :has_many_relationships
26
+
27
+ class HasManyRelationshipSerializer < ActiveModel::Serializer
28
+ attribute :body
29
+ end
30
+ end
31
+ end
32
+
33
+ resource = PrimaryResource.new(
34
+ id: 1,
35
+ title: 'title',
36
+ body: 'body',
37
+ has_many_relationships: [
38
+ HasManyRelationship.new(id: 1, body: 'body1'),
39
+ HasManyRelationship.new(id: 2, body: 'body1')
40
+ ]
41
+ )
42
+
43
+ serialization = lambda do
44
+ ActiveModelSerializers::SerializableResource.new(resource, serializer: AmsBench::PrimaryResourceSerializer).as_json
45
+ ActiveModelSerializers::SerializableResource.new(resource, namespace: AmsBench::Api::V1).as_json
46
+ ActiveModelSerializers::SerializableResource.new(resource).as_json
47
+ end
48
+
49
+ def clear_cache
50
+ AmsBench::PrimaryResourceSerializer.serializers_cache.clear
51
+ AmsBench::Api::V1::PrimaryResourceSerializer.serializers_cache.clear
52
+ ActiveModel::Serializer.serializers_cache.clear
53
+ end
54
+
55
+ configurable = lambda do
56
+ clear_cache
57
+ Benchmark.ams('Configurable Lookup Chain', time: time, disable_gc: disable_gc, &serialization)
58
+ end
59
+
60
+ old = lambda do
61
+ clear_cache
62
+ module ActiveModel
63
+ class Serializer
64
+ def self.serializer_lookup_chain_for(klass, namespace = nil)
65
+ chain = []
66
+
67
+ resource_class_name = klass.name.demodulize
68
+ resource_namespace = klass.name.deconstantize
69
+ serializer_class_name = "#{resource_class_name}Serializer"
70
+
71
+ chain.push("#{namespace}::#{serializer_class_name}") if namespace
72
+ chain.push("#{name}::#{serializer_class_name}") if self != ActiveModel::Serializer
73
+ chain.push("#{resource_namespace}::#{serializer_class_name}")
74
+ chain
75
+ end
76
+ end
77
+ end
78
+
79
+ Benchmark.ams('Old Lookup Chain (v0.10)', time: time, disable_gc: disable_gc, &serialization)
80
+ end
81
+
82
+ configurable.call
83
+ old.call
@@ -4,22 +4,46 @@ require 'tempfile'
4
4
 
5
5
  module ActiveModelSerializers
6
6
  class CacheTest < ActiveSupport::TestCase
7
- UncachedAuthor = Class.new(Author) do
7
+ # Instead of a primitive cache key (i.e. a string), this class
8
+ # returns a list of objects that require to be expanded themselves.
9
+ class AuthorWithExpandableCacheElements < Author
10
+ # For the test purposes it's important that #to_s for HasCacheKey differs
11
+ # between instances, hence not a Struct.
12
+ class HasCacheKey
13
+ attr_reader :cache_key
14
+ def initialize(cache_key)
15
+ @cache_key = cache_key
16
+ end
17
+
18
+ def to_s
19
+ "HasCacheKey##{object_id}"
20
+ end
21
+ end
22
+
23
+ def cache_key
24
+ [
25
+ HasCacheKey.new(name),
26
+ HasCacheKey.new(id)
27
+ ]
28
+ end
29
+ end
30
+
31
+ class UncachedAuthor < Author
8
32
  # To confirm cache_key is set using updated_at and cache_key option passed to cache
9
33
  undef_method :cache_key
10
34
  end
11
35
 
12
- Article = Class.new(::Model) do
36
+ class Article < ::Model
13
37
  # To confirm error is raised when cache_key is not set and cache_key option not passed to cache
14
38
  undef_method :cache_key
15
39
  end
16
40
 
17
- ArticleSerializer = Class.new(ActiveModel::Serializer) do
41
+ class ArticleSerializer < ActiveModel::Serializer
18
42
  cache only: [:place], skip_digest: true
19
43
  attributes :title
20
44
  end
21
45
 
22
- InheritedRoleSerializer = Class.new(RoleSerializer) do
46
+ class InheritedRoleSerializer < RoleSerializer
23
47
  cache key: 'inherited_role', only: [:name, :special_attribute]
24
48
  attribute :special_attribute
25
49
  end
@@ -106,6 +130,20 @@ module ActiveModelSerializers
106
130
  assert_equal(uncached_author_serializer.attributes.to_json, cache_store.fetch(key).to_json)
107
131
  end
108
132
 
133
+ def test_cache_key_expansion
134
+ author = AuthorWithExpandableCacheElements.new(id: 10, name: 'hello')
135
+ same_author = AuthorWithExpandableCacheElements.new(id: 10, name: 'hello')
136
+ diff_author = AuthorWithExpandableCacheElements.new(id: 11, name: 'hello')
137
+
138
+ author_serializer = AuthorSerializer.new(author)
139
+ same_author_serializer = AuthorSerializer.new(same_author)
140
+ diff_author_serializer = AuthorSerializer.new(diff_author)
141
+ adapter = AuthorSerializer.serialization_adapter_instance
142
+
143
+ assert_equal(author_serializer.cache_key(adapter), same_author_serializer.cache_key(adapter))
144
+ refute_equal(author_serializer.cache_key(adapter), diff_author_serializer.cache_key(adapter))
145
+ end
146
+
109
147
  def test_default_cache_key_fallback
110
148
  render_object_with_cache(@comment)
111
149
  key = "#{@comment.cache_key}/#{adapter.cache_key}"
@@ -3,7 +3,7 @@ require 'test_helper'
3
3
  module ActiveModel
4
4
  class Serializer
5
5
  class CollectionSerializerTest < ActiveSupport::TestCase
6
- MessagesSerializer = Class.new(ActiveModel::Serializer) do
6
+ class MessagesSerializer < ActiveModel::Serializer
7
7
  type 'messages'
8
8
  end
9
9
 
@@ -50,18 +50,18 @@ class ProfilePreviewSerializer < ActiveModel::Serializer
50
50
  attributes :name
51
51
  end
52
52
 
53
- Post = Class.new(Model)
54
- Like = Class.new(Model)
55
- Author = Class.new(Model)
56
- Bio = Class.new(Model)
57
- Blog = Class.new(Model)
58
- Role = Class.new(Model)
59
- User = Class.new(Model)
60
- Location = Class.new(Model)
61
- Place = Class.new(Model)
62
- Tag = Class.new(Model)
63
- VirtualValue = Class.new(Model)
64
- Comment = Class.new(Model) do
53
+ class Post < Model; end
54
+ class Like < Model; end
55
+ class Author < Model; end
56
+ class Bio < Model; end
57
+ class Blog < Model; end
58
+ class Role < Model; end
59
+ class User < Model; end
60
+ class Location < Model; end
61
+ class Place < Model; end
62
+ class Tag < Model; end
63
+ class VirtualValue < Model; end
64
+ class Comment < Model
65
65
  # Uses a custom non-time-based cache key
66
66
  def cache_key
67
67
  "#{self.class.name.downcase}/#{id}"
@@ -87,10 +87,11 @@ class PolyTag < ActiveRecord::Base
87
87
  has_many :object_tags
88
88
  end
89
89
 
90
- module Spam; end
91
- Spam::UnrelatedLink = Class.new(Model)
90
+ module Spam
91
+ class UnrelatedLink < Model; end
92
+ end
92
93
 
93
- PostSerializer = Class.new(ActiveModel::Serializer) do
94
+ class PostSerializer < ActiveModel::Serializer
94
95
  cache key: 'post', expires_in: 0.1, skip_digest: true
95
96
  attributes :id, :title, :body
96
97
 
@@ -108,12 +109,12 @@ PostSerializer = Class.new(ActiveModel::Serializer) do
108
109
  end
109
110
  end
110
111
 
111
- SpammyPostSerializer = Class.new(ActiveModel::Serializer) do
112
+ class SpammyPostSerializer < ActiveModel::Serializer
112
113
  attributes :id
113
114
  has_many :related
114
115
  end
115
116
 
116
- CommentSerializer = Class.new(ActiveModel::Serializer) do
117
+ class CommentSerializer < ActiveModel::Serializer
117
118
  cache expires_in: 1.day, skip_digest: true
118
119
  attributes :id, :body
119
120
 
@@ -125,7 +126,7 @@ CommentSerializer = Class.new(ActiveModel::Serializer) do
125
126
  end
126
127
  end
127
128
 
128
- AuthorSerializer = Class.new(ActiveModel::Serializer) do
129
+ class AuthorSerializer < ActiveModel::Serializer
129
130
  cache key: 'writer', skip_digest: true
130
131
  attribute :id
131
132
  attribute :name
@@ -135,7 +136,7 @@ AuthorSerializer = Class.new(ActiveModel::Serializer) do
135
136
  has_one :bio
136
137
  end
137
138
 
138
- RoleSerializer = Class.new(ActiveModel::Serializer) do
139
+ class RoleSerializer < ActiveModel::Serializer
139
140
  cache only: [:name, :slug], skip_digest: true
140
141
  attributes :id, :name, :description
141
142
  attribute :friendly_id, key: :slug
@@ -147,13 +148,13 @@ RoleSerializer = Class.new(ActiveModel::Serializer) do
147
148
  belongs_to :author
148
149
  end
149
150
 
150
- LikeSerializer = Class.new(ActiveModel::Serializer) do
151
+ class LikeSerializer < ActiveModel::Serializer
151
152
  attributes :id, :time
152
153
 
153
154
  belongs_to :likeable
154
155
  end
155
156
 
156
- LocationSerializer = Class.new(ActiveModel::Serializer) do
157
+ class LocationSerializer < ActiveModel::Serializer
157
158
  cache only: [:address], skip_digest: true
158
159
  attributes :id, :lat, :lng
159
160
 
@@ -164,20 +165,20 @@ LocationSerializer = Class.new(ActiveModel::Serializer) do
164
165
  end
165
166
  end
166
167
 
167
- PlaceSerializer = Class.new(ActiveModel::Serializer) do
168
+ class PlaceSerializer < ActiveModel::Serializer
168
169
  attributes :id, :name
169
170
 
170
171
  has_many :locations
171
172
  end
172
173
 
173
- BioSerializer = Class.new(ActiveModel::Serializer) do
174
+ class BioSerializer < ActiveModel::Serializer
174
175
  cache except: [:content], skip_digest: true
175
176
  attributes :id, :content, :rating
176
177
 
177
178
  belongs_to :author
178
179
  end
179
180
 
180
- BlogSerializer = Class.new(ActiveModel::Serializer) do
181
+ class BlogSerializer < ActiveModel::Serializer
181
182
  cache key: 'blog'
182
183
  attributes :id, :name
183
184
 
@@ -185,50 +186,50 @@ BlogSerializer = Class.new(ActiveModel::Serializer) do
185
186
  has_many :articles
186
187
  end
187
188
 
188
- PaginatedSerializer = Class.new(ActiveModel::Serializer::CollectionSerializer) do
189
+ class PaginatedSerializer < ActiveModel::Serializer::CollectionSerializer
189
190
  def json_key
190
191
  'paginated'
191
192
  end
192
193
  end
193
194
 
194
- AlternateBlogSerializer = Class.new(ActiveModel::Serializer) do
195
+ class AlternateBlogSerializer < ActiveModel::Serializer
195
196
  attribute :id
196
197
  attribute :name, key: :title
197
198
  end
198
199
 
199
- CustomBlogSerializer = Class.new(ActiveModel::Serializer) do
200
+ class CustomBlogSerializer < ActiveModel::Serializer
200
201
  attribute :id
201
202
  attribute :special_attribute
202
203
 
203
204
  has_many :articles
204
205
  end
205
206
 
206
- CommentPreviewSerializer = Class.new(ActiveModel::Serializer) do
207
+ class CommentPreviewSerializer < ActiveModel::Serializer
207
208
  attributes :id
208
209
 
209
210
  belongs_to :post
210
211
  end
211
212
 
212
- AuthorPreviewSerializer = Class.new(ActiveModel::Serializer) do
213
+ class AuthorPreviewSerializer < ActiveModel::Serializer
213
214
  attributes :id
214
215
 
215
216
  has_many :posts
216
217
  end
217
218
 
218
- PostPreviewSerializer = Class.new(ActiveModel::Serializer) do
219
+ class PostPreviewSerializer < ActiveModel::Serializer
219
220
  attributes :title, :body, :id
220
221
 
221
222
  has_many :comments, serializer: CommentPreviewSerializer
222
223
  belongs_to :author, serializer: AuthorPreviewSerializer
223
224
  end
224
225
 
225
- PostWithTagsSerializer = Class.new(ActiveModel::Serializer) do
226
+ class PostWithTagsSerializer < ActiveModel::Serializer
226
227
  attributes :id
227
228
 
228
229
  has_many :tags
229
230
  end
230
231
 
231
- PostWithCustomKeysSerializer = Class.new(ActiveModel::Serializer) do
232
+ class PostWithCustomKeysSerializer < ActiveModel::Serializer
232
233
  attributes :id
233
234
 
234
235
  has_many :comments, key: :reviews
@@ -236,7 +237,7 @@ PostWithCustomKeysSerializer = Class.new(ActiveModel::Serializer) do
236
237
  has_one :blog, key: :site
237
238
  end
238
239
 
239
- VirtualValueSerializer = Class.new(ActiveModel::Serializer) do
240
+ class VirtualValueSerializer < ActiveModel::Serializer
240
241
  attributes :id
241
242
 
242
243
  has_many :reviews, virtual_value: [{ type: 'reviews', id: '1' },
@@ -250,34 +251,36 @@ VirtualValueSerializer = Class.new(ActiveModel::Serializer) do
250
251
  end
251
252
  end
252
253
 
253
- PolymorphicHasManySerializer = Class.new(ActiveModel::Serializer) do
254
+ class PolymorphicHasManySerializer < ActiveModel::Serializer
254
255
  attributes :id, :name
255
256
  end
256
257
 
257
- PolymorphicBelongsToSerializer = Class.new(ActiveModel::Serializer) do
258
+ class PolymorphicBelongsToSerializer < ActiveModel::Serializer
258
259
  attributes :id, :title
259
260
 
260
261
  has_one :imageable, serializer: PolymorphicHasManySerializer, polymorphic: true
261
262
  end
262
263
 
263
- PolymorphicSimpleSerializer = Class.new(ActiveModel::Serializer) do
264
+ class PolymorphicSimpleSerializer < ActiveModel::Serializer
264
265
  attributes :id
265
266
  end
266
267
 
267
- PolymorphicObjectTagSerializer = Class.new(ActiveModel::Serializer) do
268
+ class PolymorphicObjectTagSerializer < ActiveModel::Serializer
268
269
  attributes :id
269
270
 
270
271
  has_many :taggable, serializer: PolymorphicSimpleSerializer, polymorphic: true
271
272
  end
272
273
 
273
- PolymorphicTagSerializer = Class.new(ActiveModel::Serializer) do
274
+ class PolymorphicTagSerializer < ActiveModel::Serializer
274
275
  attributes :id, :phrase
275
276
 
276
277
  has_many :object_tags, serializer: PolymorphicObjectTagSerializer
277
278
  end
278
279
 
279
- Spam::UnrelatedLinkSerializer = Class.new(ActiveModel::Serializer) do
280
- cache only: [:id]
281
- attributes :id
280
+ module Spam
281
+ class UnrelatedLinkSerializer < ActiveModel::Serializer
282
+ cache only: [:id]
283
+ attributes :id
284
+ end
282
285
  end
283
286
  $VERBOSE = verbose