active_model_serializers 0.10.0 → 0.10.9

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 (206) hide show
  1. checksums.yaml +5 -5
  2. data/.rubocop.yml +10 -5
  3. data/.travis.yml +41 -21
  4. data/CHANGELOG.md +200 -2
  5. data/CODE_OF_CONDUCT.md +74 -0
  6. data/Gemfile +25 -4
  7. data/README.md +166 -28
  8. data/Rakefile +5 -32
  9. data/active_model_serializers.gemspec +23 -25
  10. data/appveyor.yml +10 -6
  11. data/bin/rubocop +38 -0
  12. data/docs/README.md +2 -1
  13. data/docs/general/adapters.md +35 -11
  14. data/docs/general/caching.md +7 -1
  15. data/docs/general/configuration_options.md +86 -1
  16. data/docs/general/deserialization.md +1 -1
  17. data/docs/general/fields.md +31 -0
  18. data/docs/general/getting_started.md +1 -1
  19. data/docs/general/logging.md +7 -0
  20. data/docs/general/rendering.md +63 -25
  21. data/docs/general/serializers.md +137 -14
  22. data/docs/howto/add_pagination_links.md +16 -17
  23. data/docs/howto/add_relationship_links.md +140 -0
  24. data/docs/howto/add_root_key.md +11 -0
  25. data/docs/howto/grape_integration.md +42 -0
  26. data/docs/howto/outside_controller_use.md +12 -4
  27. data/docs/howto/passing_arbitrary_options.md +2 -2
  28. data/docs/howto/serialize_poro.md +46 -5
  29. data/docs/howto/test.md +2 -0
  30. data/docs/howto/upgrade_from_0_8_to_0_10.md +265 -0
  31. data/docs/integrations/ember-and-json-api.md +67 -32
  32. data/docs/jsonapi/schema.md +1 -1
  33. data/lib/action_controller/serialization.rb +15 -3
  34. data/lib/active_model/serializable_resource.rb +2 -0
  35. data/lib/active_model/serializer/adapter/attributes.rb +2 -0
  36. data/lib/active_model/serializer/adapter/base.rb +4 -0
  37. data/lib/active_model/serializer/adapter/json.rb +2 -0
  38. data/lib/active_model/serializer/adapter/json_api.rb +2 -0
  39. data/lib/active_model/serializer/adapter/null.rb +2 -0
  40. data/lib/active_model/serializer/adapter.rb +2 -0
  41. data/lib/active_model/serializer/array_serializer.rb +10 -5
  42. data/lib/active_model/serializer/association.rb +64 -10
  43. data/lib/active_model/serializer/attribute.rb +2 -0
  44. data/lib/active_model/serializer/belongs_to_reflection.rb +6 -3
  45. data/lib/active_model/serializer/collection_serializer.rb +39 -13
  46. data/lib/active_model/serializer/{caching.rb → concerns/caching.rb} +87 -116
  47. data/lib/active_model/serializer/error_serializer.rb +13 -7
  48. data/lib/active_model/serializer/errors_serializer.rb +27 -20
  49. data/lib/active_model/serializer/field.rb +2 -0
  50. data/lib/active_model/serializer/fieldset.rb +2 -0
  51. data/lib/active_model/serializer/has_many_reflection.rb +5 -3
  52. data/lib/active_model/serializer/has_one_reflection.rb +3 -4
  53. data/lib/active_model/serializer/lazy_association.rb +99 -0
  54. data/lib/active_model/serializer/link.rb +23 -0
  55. data/lib/active_model/serializer/lint.rb +136 -130
  56. data/lib/active_model/serializer/null.rb +2 -0
  57. data/lib/active_model/serializer/reflection.rb +132 -67
  58. data/lib/active_model/serializer/version.rb +3 -1
  59. data/lib/active_model/serializer.rb +308 -82
  60. data/lib/active_model_serializers/adapter/attributes.rb +5 -66
  61. data/lib/active_model_serializers/adapter/base.rb +41 -39
  62. data/lib/active_model_serializers/adapter/json.rb +2 -0
  63. data/lib/active_model_serializers/adapter/json_api/deserialization.rb +4 -2
  64. data/lib/active_model_serializers/adapter/json_api/error.rb +2 -0
  65. data/lib/active_model_serializers/adapter/json_api/jsonapi.rb +2 -0
  66. data/lib/active_model_serializers/adapter/json_api/link.rb +3 -1
  67. data/lib/active_model_serializers/adapter/json_api/meta.rb +2 -0
  68. data/lib/active_model_serializers/adapter/json_api/pagination_links.rb +49 -21
  69. data/lib/active_model_serializers/adapter/json_api/relationship.rb +77 -23
  70. data/lib/active_model_serializers/adapter/json_api/resource_identifier.rb +41 -10
  71. data/lib/active_model_serializers/adapter/json_api.rb +84 -65
  72. data/lib/active_model_serializers/adapter/null.rb +2 -0
  73. data/lib/active_model_serializers/adapter.rb +9 -1
  74. data/lib/active_model_serializers/callbacks.rb +2 -0
  75. data/lib/active_model_serializers/deprecate.rb +3 -2
  76. data/lib/active_model_serializers/deserialization.rb +4 -0
  77. data/lib/active_model_serializers/json_pointer.rb +2 -0
  78. data/lib/active_model_serializers/logging.rb +2 -0
  79. data/lib/active_model_serializers/lookup_chain.rb +82 -0
  80. data/lib/active_model_serializers/model.rb +111 -28
  81. data/lib/active_model_serializers/railtie.rb +7 -1
  82. data/lib/active_model_serializers/register_jsonapi_renderer.rb +46 -31
  83. data/lib/active_model_serializers/serializable_resource.rb +10 -7
  84. data/lib/active_model_serializers/serialization_context.rb +12 -3
  85. data/lib/active_model_serializers/test/schema.rb +4 -2
  86. data/lib/active_model_serializers/test/serializer.rb +2 -0
  87. data/lib/active_model_serializers/test.rb +2 -0
  88. data/lib/active_model_serializers.rb +35 -10
  89. data/lib/generators/rails/resource_override.rb +3 -1
  90. data/lib/generators/rails/serializer_generator.rb +6 -4
  91. data/lib/grape/active_model_serializers.rb +9 -5
  92. data/lib/grape/formatters/active_model_serializers.rb +21 -2
  93. data/lib/grape/helpers/active_model_serializers.rb +3 -0
  94. data/lib/tasks/rubocop.rake +55 -0
  95. data/test/action_controller/adapter_selector_test.rb +16 -5
  96. data/test/action_controller/explicit_serializer_test.rb +7 -4
  97. data/test/action_controller/json/include_test.rb +108 -27
  98. data/test/action_controller/json_api/deserialization_test.rb +3 -1
  99. data/test/action_controller/json_api/errors_test.rb +10 -9
  100. data/test/action_controller/json_api/fields_test.rb +68 -0
  101. data/test/action_controller/json_api/linked_test.rb +31 -24
  102. data/test/action_controller/json_api/pagination_test.rb +33 -23
  103. data/test/action_controller/json_api/transform_test.rb +13 -3
  104. data/test/action_controller/lookup_proc_test.rb +51 -0
  105. data/test/action_controller/namespace_lookup_test.rb +234 -0
  106. data/test/action_controller/serialization_scope_name_test.rb +14 -6
  107. data/test/action_controller/serialization_test.rb +23 -12
  108. data/test/active_model_serializers/adapter_for_test.rb +2 -0
  109. data/test/active_model_serializers/json_pointer_test.rb +17 -13
  110. data/test/active_model_serializers/logging_test.rb +2 -0
  111. data/test/active_model_serializers/model_test.rb +139 -4
  112. data/test/active_model_serializers/railtie_test_isolated.rb +14 -7
  113. data/test/active_model_serializers/register_jsonapi_renderer_test_isolated.rb +163 -0
  114. data/test/active_model_serializers/serialization_context_test_isolated.rb +25 -10
  115. data/test/active_model_serializers/test/schema_test.rb +5 -2
  116. data/test/active_model_serializers/test/serializer_test.rb +2 -0
  117. data/test/active_record_test.rb +2 -0
  118. data/test/adapter/attributes_test.rb +42 -0
  119. data/test/adapter/deprecation_test.rb +2 -0
  120. data/test/adapter/json/belongs_to_test.rb +2 -0
  121. data/test/adapter/json/collection_test.rb +16 -0
  122. data/test/adapter/json/has_many_test.rb +12 -2
  123. data/test/adapter/json/transform_test.rb +17 -15
  124. data/test/adapter/json_api/belongs_to_test.rb +2 -0
  125. data/test/adapter/json_api/collection_test.rb +6 -3
  126. data/test/adapter/json_api/errors_test.rb +19 -19
  127. data/test/adapter/json_api/fields_test.rb +14 -3
  128. data/test/adapter/json_api/has_many_explicit_serializer_test.rb +2 -0
  129. data/test/adapter/json_api/has_many_test.rb +51 -20
  130. data/test/adapter/json_api/has_one_test.rb +2 -0
  131. data/test/adapter/json_api/include_data_if_sideloaded_test.rb +215 -0
  132. data/test/adapter/json_api/json_api_test.rb +7 -7
  133. data/test/adapter/json_api/linked_test.rb +35 -12
  134. data/test/adapter/json_api/links_test.rb +22 -3
  135. data/test/adapter/json_api/pagination_links_test.rb +55 -13
  136. data/test/adapter/json_api/parse_test.rb +3 -1
  137. data/test/adapter/json_api/relationship_test.rb +311 -73
  138. data/test/adapter/json_api/resource_meta_test.rb +5 -3
  139. data/test/adapter/json_api/toplevel_jsonapi_test.rb +2 -0
  140. data/test/adapter/json_api/transform_test.rb +265 -253
  141. data/test/adapter/json_api/type_test.rb +170 -36
  142. data/test/adapter/json_test.rb +10 -7
  143. data/test/adapter/null_test.rb +3 -2
  144. data/test/adapter/polymorphic_test.rb +54 -5
  145. data/test/adapter_test.rb +3 -1
  146. data/test/array_serializer_test.rb +2 -0
  147. data/test/benchmark/app.rb +3 -1
  148. data/test/benchmark/benchmarking_support.rb +3 -1
  149. data/test/benchmark/bm_active_record.rb +83 -0
  150. data/test/benchmark/bm_adapter.rb +40 -0
  151. data/test/benchmark/bm_caching.rb +18 -16
  152. data/test/benchmark/bm_lookup_chain.rb +85 -0
  153. data/test/benchmark/bm_transform.rb +23 -10
  154. data/test/benchmark/controllers.rb +18 -17
  155. data/test/benchmark/fixtures.rb +74 -72
  156. data/test/cache_test.rb +301 -69
  157. data/test/collection_serializer_test.rb +33 -14
  158. data/test/fixtures/active_record.rb +47 -10
  159. data/test/fixtures/poro.rb +128 -183
  160. data/test/generators/scaffold_controller_generator_test.rb +2 -0
  161. data/test/generators/serializer_generator_test.rb +25 -5
  162. data/test/grape_test.rb +172 -56
  163. data/test/lint_test.rb +3 -1
  164. data/test/logger_test.rb +15 -11
  165. data/test/poro_test.rb +2 -0
  166. data/test/serializable_resource_test.rb +20 -22
  167. data/test/serializers/association_macros_test.rb +5 -2
  168. data/test/serializers/associations_test.rb +274 -49
  169. data/test/serializers/attribute_test.rb +7 -3
  170. data/test/serializers/attributes_test.rb +3 -1
  171. data/test/serializers/caching_configuration_test_isolated.rb +8 -6
  172. data/test/serializers/configuration_test.rb +2 -0
  173. data/test/serializers/fieldset_test.rb +3 -1
  174. data/test/serializers/meta_test.rb +14 -6
  175. data/test/serializers/options_test.rb +19 -6
  176. data/test/serializers/read_attribute_for_serialization_test.rb +5 -3
  177. data/test/serializers/reflection_test.rb +481 -0
  178. data/test/serializers/root_test.rb +3 -1
  179. data/test/serializers/serialization_test.rb +4 -2
  180. data/test/serializers/serializer_for_test.rb +14 -10
  181. data/test/serializers/serializer_for_with_namespace_test.rb +90 -0
  182. data/test/support/isolated_unit.rb +11 -4
  183. data/test/support/rails5_shims.rb +10 -2
  184. data/test/support/rails_app.rb +4 -9
  185. data/test/support/serialization_testing.rb +33 -5
  186. data/test/test_helper.rb +15 -0
  187. metadata +126 -46
  188. data/.rubocop_todo.yml +0 -167
  189. data/docs/ARCHITECTURE.md +0 -126
  190. data/lib/active_model/serializer/associations.rb +0 -100
  191. data/lib/active_model/serializer/attributes.rb +0 -82
  192. data/lib/active_model/serializer/collection_reflection.rb +0 -7
  193. data/lib/active_model/serializer/configuration.rb +0 -35
  194. data/lib/active_model/serializer/include_tree.rb +0 -111
  195. data/lib/active_model/serializer/links.rb +0 -35
  196. data/lib/active_model/serializer/meta.rb +0 -29
  197. data/lib/active_model/serializer/singular_reflection.rb +0 -7
  198. data/lib/active_model/serializer/type.rb +0 -25
  199. data/lib/active_model_serializers/key_transform.rb +0 -70
  200. data/test/active_model_serializers/key_transform_test.rb +0 -263
  201. data/test/adapter/json_api/has_many_embed_ids_test.rb +0 -43
  202. data/test/adapter/json_api/relationships_test.rb +0 -199
  203. data/test/adapter/json_api/resource_identifier_test.rb +0 -85
  204. data/test/include_tree/from_include_args_test.rb +0 -26
  205. data/test/include_tree/from_string_test.rb +0 -94
  206. data/test/include_tree/include_args_to_hash_test.rb +0 -64
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'active_record'
2
4
 
3
5
  ActiveRecord::Base.establish_connection(adapter: 'sqlite3', database: ':memory:')
@@ -47,16 +49,6 @@ module ARModels
47
49
  has_many :comments
48
50
  belongs_to :author
49
51
  end
50
-
51
- class Comment < ActiveRecord::Base
52
- belongs_to :post
53
- belongs_to :author
54
- end
55
-
56
- class Author < ActiveRecord::Base
57
- has_many :posts
58
- end
59
-
60
52
  class PostSerializer < ActiveModel::Serializer
61
53
  attributes :id, :title, :body
62
54
 
@@ -64,15 +56,60 @@ module ARModels
64
56
  belongs_to :author
65
57
  end
66
58
 
59
+ class Comment < ActiveRecord::Base
60
+ belongs_to :post
61
+ belongs_to :author
62
+ end
67
63
  class CommentSerializer < ActiveModel::Serializer
68
64
  attributes :id, :contents
69
65
 
70
66
  belongs_to :author
71
67
  end
72
68
 
69
+ class Author < ActiveRecord::Base
70
+ has_many :posts
71
+ end
73
72
  class AuthorSerializer < ActiveModel::Serializer
74
73
  attributes :id, :name
75
74
 
76
75
  has_many :posts
77
76
  end
78
77
  end
78
+
79
+ class Employee < ActiveRecord::Base
80
+ has_many :pictures, as: :imageable
81
+ has_many :object_tags, as: :taggable
82
+ end
83
+
84
+ class PolymorphicSimpleSerializer < ActiveModel::Serializer
85
+ attributes :id
86
+ end
87
+
88
+ class ObjectTag < ActiveRecord::Base
89
+ belongs_to :poly_tag
90
+ belongs_to :taggable, polymorphic: true
91
+ end
92
+ class PolymorphicObjectTagSerializer < ActiveModel::Serializer
93
+ attributes :id
94
+ belongs_to :taggable, serializer: PolymorphicSimpleSerializer, polymorphic: true
95
+ end
96
+
97
+ class PolyTag < ActiveRecord::Base
98
+ has_many :object_tags
99
+ end
100
+ class PolymorphicTagSerializer < ActiveModel::Serializer
101
+ attributes :id, :phrase
102
+ has_many :object_tags, serializer: PolymorphicObjectTagSerializer
103
+ end
104
+
105
+ class Picture < ActiveRecord::Base
106
+ belongs_to :imageable, polymorphic: true
107
+ has_many :object_tags, as: :taggable
108
+ end
109
+ class PolymorphicHasManySerializer < ActiveModel::Serializer
110
+ attributes :id, :name
111
+ end
112
+ class PolymorphicBelongsToSerializer < ActiveModel::Serializer
113
+ attributes :id, :title
114
+ belongs_to :imageable, serializer: PolymorphicHasManySerializer, polymorphic: true
115
+ end
@@ -1,25 +1,30 @@
1
- verbose = $VERBOSE
2
- $VERBOSE = nil
1
+ # frozen_string_literal: true
2
+
3
3
  class Model < ActiveModelSerializers::Model
4
- FILE_DIGEST = Digest::MD5.hexdigest(File.open(__FILE__).read)
5
-
6
- ### Helper methods, not required to be serializable
7
-
8
- # Convenience when not adding @attributes readers and writers
9
- def method_missing(meth, *args)
10
- if meth.to_s =~ /^(.*)=$/
11
- attributes[$1.to_sym] = args[0]
12
- elsif attributes.key?(meth)
13
- attributes[meth]
14
- else
15
- super
4
+ rand(2).zero? && derive_attributes_from_names_and_fix_accessors
5
+
6
+ attr_writer :id
7
+
8
+ # At this time, just for organization of intent
9
+ class_attribute :association_names
10
+ self.association_names = []
11
+
12
+ def self.associations(*names)
13
+ self.association_names |= names.map(&:to_sym)
14
+ # Silence redefinition of methods warnings
15
+ ActiveModelSerializers.silence_warnings do
16
+ attr_accessor(*names)
16
17
  end
17
18
  end
18
19
 
19
- # required for ActiveModel::AttributeAssignment#_assign_attribute
20
- # in Rails 5
21
- def respond_to_missing?(method_name, _include_private = false)
22
- attributes.key?(method_name.to_s.tr('=', '').to_sym) || super
20
+ def associations
21
+ association_names.each_with_object({}) do |association_name, result|
22
+ result[association_name] = public_send(association_name).freeze
23
+ end.with_indifferent_access.freeze
24
+ end
25
+
26
+ def attributes
27
+ super.except(*association_names)
23
28
  end
24
29
  end
25
30
 
@@ -30,67 +35,60 @@ end
30
35
  # model = ModelWithErrors.new
31
36
  # model.validate! # => ["cannot be nil"]
32
37
  # model.errors.full_messages # => ["name cannot be nil"]
33
- class ModelWithErrors < ::ActiveModelSerializers::Model
34
- attr_accessor :name
38
+ class ModelWithErrors < Model
39
+ attributes :name
35
40
  end
36
41
 
37
42
  class Profile < Model
43
+ attributes :name, :description
44
+ associations :comments
38
45
  end
39
-
40
46
  class ProfileSerializer < ActiveModel::Serializer
41
47
  attributes :name, :description
42
-
43
- # TODO: is this used anywhere?
44
- def arguments_passed_in?
45
- instance_options[:my_options] == :accessible
46
- end
47
48
  end
48
-
49
49
  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
65
- # Uses a custom non-time-based cache key
66
- def cache_key
67
- "#{self.class.name.downcase}/#{self.id}"
68
- end
53
+ class Author < Model
54
+ attributes :name
55
+ associations :posts, :bio, :roles, :comments
69
56
  end
57
+ class AuthorSerializer < ActiveModel::Serializer
58
+ cache key: 'writer', skip_digest: true
59
+ attribute :id
60
+ attribute :name
70
61
 
71
- class Employee < ActiveRecord::Base
72
- has_many :pictures, as: :imageable
73
- has_many :object_tags, as: :taggable
62
+ has_many :posts
63
+ has_many :roles
64
+ has_one :bio
74
65
  end
75
-
76
- class ObjectTag < ActiveRecord::Base
77
- belongs_to :poly_tag
78
- belongs_to :taggable, polymorphic: true
66
+ class AuthorPreviewSerializer < ActiveModel::Serializer
67
+ attributes :id
68
+ has_many :posts
79
69
  end
80
70
 
81
- class Picture < ActiveRecord::Base
82
- belongs_to :imageable, polymorphic: true
83
- has_many :object_tags, as: :taggable
71
+ class Comment < Model
72
+ attributes :body, :date
73
+ associations :post, :author, :likes
84
74
  end
85
-
86
- class PolyTag < ActiveRecord::Base
87
- has_many :object_tags
75
+ class CommentSerializer < ActiveModel::Serializer
76
+ cache expires_in: 1.day, skip_digest: true
77
+ attributes :id, :body
78
+ belongs_to :post
79
+ belongs_to :author
88
80
  end
81
+ class CommentPreviewSerializer < ActiveModel::Serializer
82
+ attributes :id
89
83
 
90
- module Spam; end
91
- Spam::UnrelatedLink = Class.new(Model)
84
+ belongs_to :post
85
+ end
92
86
 
93
- PostSerializer = Class.new(ActiveModel::Serializer) do
87
+ class Post < Model
88
+ attributes :title, :body
89
+ associations :author, :comments, :blog, :tags, :related
90
+ end
91
+ class PostSerializer < ActiveModel::Serializer
94
92
  cache key: 'post', expires_in: 0.1, skip_digest: true
95
93
  attributes :id, :title, :body
96
94
 
@@ -101,143 +99,116 @@ PostSerializer = Class.new(ActiveModel::Serializer) do
101
99
  def blog
102
100
  Blog.new(id: 999, name: 'Custom blog')
103
101
  end
104
-
105
- # TODO: is this used anywhere?
106
- def custom_options
107
- instance_options
108
- end
109
102
  end
110
-
111
- SpammyPostSerializer = Class.new(ActiveModel::Serializer) do
103
+ class SpammyPostSerializer < ActiveModel::Serializer
112
104
  attributes :id
113
105
  has_many :related
114
106
  end
107
+ class PostPreviewSerializer < ActiveModel::Serializer
108
+ attributes :title, :body, :id
115
109
 
116
- CommentSerializer = Class.new(ActiveModel::Serializer) do
117
- cache expires_in: 1.day, skip_digest: true
118
- attributes :id, :body
119
-
120
- belongs_to :post
121
- belongs_to :author
122
-
123
- def custom_options
124
- instance_options
125
- end
126
- end
127
-
128
- AuthorSerializer = Class.new(ActiveModel::Serializer) do
129
- cache key: 'writer', skip_digest: true
130
- attribute :id
131
- attribute :name
132
-
133
- has_many :posts
134
- has_many :roles
135
- has_one :bio
136
- end
137
-
138
- RoleSerializer = Class.new(ActiveModel::Serializer) do
139
- cache only: [:name], skip_digest: true
140
- attributes :id, :name, :description, :slug
141
-
142
- def slug
143
- "#{object.name}-#{object.id}"
144
- end
145
-
146
- belongs_to :author
147
- end
148
-
149
- LikeSerializer = Class.new(ActiveModel::Serializer) do
150
- attributes :id, :time
151
-
152
- belongs_to :likeable
110
+ has_many :comments, serializer: ::CommentPreviewSerializer
111
+ belongs_to :author, serializer: ::AuthorPreviewSerializer
153
112
  end
154
-
155
- LocationSerializer = Class.new(ActiveModel::Serializer) do
156
- cache only: [:place], skip_digest: true
157
- attributes :id, :lat, :lng
158
-
159
- belongs_to :place
160
-
161
- def place
162
- 'Nowhere'
163
- end
113
+ class PostWithCustomKeysSerializer < ActiveModel::Serializer
114
+ attributes :id
115
+ has_many :comments, key: :reviews
116
+ belongs_to :author, key: :writer
117
+ has_one :blog, key: :site
164
118
  end
165
119
 
166
- PlaceSerializer = Class.new(ActiveModel::Serializer) do
167
- attributes :id, :name
168
-
169
- has_many :locations
120
+ class Bio < Model
121
+ attributes :content, :rating
122
+ associations :author
170
123
  end
171
-
172
- BioSerializer = Class.new(ActiveModel::Serializer) do
124
+ class BioSerializer < ActiveModel::Serializer
173
125
  cache except: [:content], skip_digest: true
174
126
  attributes :id, :content, :rating
175
127
 
176
128
  belongs_to :author
177
129
  end
178
130
 
179
- BlogSerializer = Class.new(ActiveModel::Serializer) do
131
+ class Blog < Model
132
+ attributes :name, :type, :special_attribute
133
+ associations :writer, :articles
134
+ end
135
+ class BlogSerializer < ActiveModel::Serializer
180
136
  cache key: 'blog'
181
137
  attributes :id, :name
182
138
 
183
139
  belongs_to :writer
184
140
  has_many :articles
185
141
  end
186
-
187
- PaginatedSerializer = Class.new(ActiveModel::Serializer::CollectionSerializer) do
188
- def json_key
189
- 'paginated'
190
- end
191
- end
192
-
193
- AlternateBlogSerializer = Class.new(ActiveModel::Serializer) do
142
+ class AlternateBlogSerializer < ActiveModel::Serializer
194
143
  attribute :id
195
144
  attribute :name, key: :title
196
145
  end
197
-
198
- CustomBlogSerializer = Class.new(ActiveModel::Serializer) do
146
+ class CustomBlogSerializer < ActiveModel::Serializer
199
147
  attribute :id
200
148
  attribute :special_attribute
201
-
202
149
  has_many :articles
203
150
  end
204
151
 
205
- CommentPreviewSerializer = Class.new(ActiveModel::Serializer) do
206
- attributes :id
207
-
208
- belongs_to :post
152
+ class Role < Model
153
+ attributes :name, :description, :special_attribute
154
+ associations :author
209
155
  end
156
+ class RoleSerializer < ActiveModel::Serializer
157
+ cache only: [:name, :slug], skip_digest: true
158
+ attributes :id, :name, :description
159
+ attribute :friendly_id, key: :slug
160
+ belongs_to :author
210
161
 
211
- AuthorPreviewSerializer = Class.new(ActiveModel::Serializer) do
212
- attributes :id
162
+ def friendly_id
163
+ "#{object.name}-#{object.id}"
164
+ end
165
+ end
213
166
 
214
- has_many :posts
167
+ class Location < Model
168
+ attributes :lat, :lng
169
+ associations :place
215
170
  end
171
+ class LocationSerializer < ActiveModel::Serializer
172
+ cache only: [:address], skip_digest: true
173
+ attributes :id, :lat, :lng
216
174
 
217
- PostPreviewSerializer = Class.new(ActiveModel::Serializer) do
218
- attributes :title, :body, :id
175
+ belongs_to :place, key: :address
219
176
 
220
- has_many :comments, serializer: CommentPreviewSerializer
221
- belongs_to :author, serializer: AuthorPreviewSerializer
177
+ def place
178
+ 'Nowhere'
179
+ end
222
180
  end
223
181
 
224
- PostWithTagsSerializer = Class.new(ActiveModel::Serializer) do
225
- attributes :id
226
-
227
- has_many :tags
182
+ class Place < Model
183
+ attributes :name
184
+ associations :locations
185
+ end
186
+ class PlaceSerializer < ActiveModel::Serializer
187
+ attributes :id, :name
188
+ has_many :locations
228
189
  end
229
190
 
230
- PostWithCustomKeysSerializer = Class.new(ActiveModel::Serializer) do
231
- attributes :id
191
+ class Like < Model
192
+ attributes :time
193
+ associations :likeable
194
+ end
195
+ class LikeSerializer < ActiveModel::Serializer
196
+ attributes :id, :time
197
+ belongs_to :likeable
198
+ end
232
199
 
233
- has_many :comments, key: :reviews
234
- belongs_to :author, key: :writer
235
- has_one :blog, key: :site
200
+ module Spam
201
+ class UnrelatedLink < Model
202
+ end
203
+ class UnrelatedLinkSerializer < ActiveModel::Serializer
204
+ cache only: [:id]
205
+ attributes :id
206
+ end
236
207
  end
237
208
 
238
- VirtualValueSerializer = Class.new(ActiveModel::Serializer) do
209
+ class VirtualValue < Model; end
210
+ class VirtualValueSerializer < ActiveModel::Serializer
239
211
  attributes :id
240
-
241
212
  has_many :reviews, virtual_value: [{ type: 'reviews', id: '1' },
242
213
  { type: 'reviews', id: '2' }]
243
214
  has_one :maker, virtual_value: { type: 'makers', id: '1' }
@@ -249,34 +220,8 @@ VirtualValueSerializer = Class.new(ActiveModel::Serializer) do
249
220
  end
250
221
  end
251
222
 
252
- PolymorphicHasManySerializer = Class.new(ActiveModel::Serializer) do
253
- attributes :id, :name
254
- end
255
-
256
- PolymorphicBelongsToSerializer = Class.new(ActiveModel::Serializer) do
257
- attributes :id, :title
258
-
259
- has_one :imageable, serializer: PolymorphicHasManySerializer, polymorphic: true
260
- end
261
-
262
- PolymorphicSimpleSerializer = Class.new(ActiveModel::Serializer) do
263
- attributes :id
264
- end
265
-
266
- PolymorphicObjectTagSerializer = Class.new(ActiveModel::Serializer) do
267
- attributes :id
268
-
269
- has_many :taggable, serializer: PolymorphicSimpleSerializer, polymorphic: true
270
- end
271
-
272
- PolymorphicTagSerializer = Class.new(ActiveModel::Serializer) do
273
- attributes :id, :phrase
274
-
275
- has_many :object_tags, serializer: PolymorphicObjectTagSerializer
276
- end
277
-
278
- Spam::UnrelatedLinkSerializer = Class.new(ActiveModel::Serializer) do
279
- cache only: [:id]
280
- attributes :id
223
+ class PaginatedSerializer < ActiveModel::Serializer::CollectionSerializer
224
+ def json_key
225
+ 'paginated'
226
+ end
281
227
  end
282
- $VERBOSE = verbose
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'test_helper'
2
4
  require 'generators/rails/resource_override'
3
5
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'test_helper'
2
4
  require 'generators/rails/resource_override'
3
5
  require 'generators/rails/serializer_generator'
@@ -20,11 +22,10 @@ class SerializerGeneratorTest < Rails::Generators::TestCase
20
22
  end
21
23
 
22
24
  def test_uses_application_serializer_if_one_exists
23
- Object.const_set(:ApplicationSerializer, Class.new)
24
- run_generator
25
- assert_file 'app/serializers/account_serializer.rb', /class AccountSerializer < ApplicationSerializer/
26
- ensure
27
- Object.send :remove_const, :ApplicationSerializer
25
+ stub_safe_constantize(expected: 'ApplicationSerializer') do
26
+ run_generator
27
+ assert_file 'app/serializers/account_serializer.rb', /class AccountSerializer < ApplicationSerializer/
28
+ end
28
29
  end
29
30
 
30
31
  def test_uses_given_parent
@@ -54,4 +55,23 @@ class SerializerGeneratorTest < Rails::Generators::TestCase
54
55
  end
55
56
  end
56
57
  end
58
+
59
+ private
60
+
61
+ def stub_safe_constantize(expected:)
62
+ String.class_eval do
63
+ alias_method :old, :safe_constantize
64
+ end
65
+ String.send(:define_method, :safe_constantize) do
66
+ Class if self == expected
67
+ end
68
+
69
+ yield
70
+ ensure
71
+ String.class_eval do
72
+ undef_method :safe_constantize
73
+ alias_method :safe_constantize, :old
74
+ undef_method :old
75
+ end
76
+ end
57
77
  end