active_model_serializers 0.10.0.rc1 → 0.10.0.rc2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (52) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +1 -2
  3. data/Gemfile +1 -1
  4. data/README.md +6 -3
  5. data/lib/action_controller/serialization.rb +9 -1
  6. data/lib/active_model/serializer.rb +15 -21
  7. data/lib/active_model/serializer/adapter.rb +13 -4
  8. data/lib/active_model/serializer/adapter/flatten_json.rb +12 -0
  9. data/lib/active_model/serializer/adapter/fragment_cache.rb +5 -5
  10. data/lib/active_model/serializer/adapter/json.rb +8 -10
  11. data/lib/active_model/serializer/adapter/json_api.rb +34 -30
  12. data/lib/active_model/serializer/adapter/json_api/fragment_cache.rb +3 -2
  13. data/lib/active_model/serializer/array_serializer.rb +8 -5
  14. data/lib/active_model/serializer/configuration.rb +1 -1
  15. data/lib/active_model/serializer/fieldset.rb +2 -2
  16. data/lib/active_model/serializer/railtie.rb +8 -0
  17. data/lib/active_model/serializer/version.rb +1 -1
  18. data/lib/active_model_serializers.rb +1 -0
  19. data/lib/generators/serializer/resource_override.rb +12 -0
  20. data/test/action_controller/adapter_selector_test.rb +7 -5
  21. data/test/action_controller/explicit_serializer_test.rb +33 -9
  22. data/test/action_controller/json_api_linked_test.rb +25 -19
  23. data/test/action_controller/rescue_from_test.rb +32 -0
  24. data/test/action_controller/serialization_scope_name_test.rb +2 -2
  25. data/test/action_controller/serialization_test.rb +41 -23
  26. data/test/adapter/fragment_cache_test.rb +1 -1
  27. data/test/adapter/json/belongs_to_test.rb +9 -2
  28. data/test/adapter/json/collection_test.rb +16 -2
  29. data/test/adapter/json/has_many_test.rb +1 -1
  30. data/test/adapter/json_api/belongs_to_test.rb +45 -35
  31. data/test/adapter/json_api/collection_test.rb +30 -23
  32. data/test/adapter/json_api/has_many_embed_ids_test.rb +2 -2
  33. data/test/adapter/json_api/has_many_explicit_serializer_test.rb +14 -14
  34. data/test/adapter/json_api/has_many_test.rb +22 -18
  35. data/test/adapter/json_api/has_one_test.rb +8 -6
  36. data/test/adapter/json_api/linked_test.rb +97 -71
  37. data/test/adapter/json_test.rb +1 -1
  38. data/test/adapter_test.rb +1 -1
  39. data/test/array_serializer_test.rb +14 -0
  40. data/test/fixtures/poro.rb +31 -7
  41. data/test/generators/scaffold_controller_generator_test.rb +24 -0
  42. data/test/{serializers/generators_test.rb → generators/serializer_generator_test.rb} +2 -10
  43. data/test/serializers/adapter_for_test.rb +1 -1
  44. data/test/serializers/associations_test.rb +21 -0
  45. data/test/serializers/attribute_test.rb +16 -1
  46. data/test/serializers/attributes_test.rb +35 -0
  47. data/test/serializers/cache_test.rb +14 -4
  48. data/test/serializers/configuration_test.rb +1 -1
  49. data/test/serializers/meta_test.rb +38 -9
  50. data/test/serializers/serializer_for_test.rb +9 -0
  51. data/test/test_helper.rb +10 -7
  52. metadata +12 -5
@@ -30,9 +30,9 @@ module ActiveModel
30
30
  end
31
31
 
32
32
  def test_includes_bio_id
33
- expected = { linkage: { type: "bios", id: "43" } }
33
+ expected = { data: { type: "bios", id: "43" } }
34
34
 
35
- assert_equal(expected, @adapter.serializable_hash[:data][:links][:bio])
35
+ assert_equal(expected, @adapter.serializable_hash[:data][:relationships][:bio])
36
36
  end
37
37
 
38
38
  def test_includes_linked_bio
@@ -41,11 +41,13 @@ module ActiveModel
41
41
  expected = [
42
42
  {
43
43
  id: "43",
44
- rating: nil,
45
44
  type: "bios",
46
- content:"AMS Contributor",
47
- links: {
48
- author: { linkage: { type: "authors", id: "1" } }
45
+ attributes: {
46
+ content:"AMS Contributor",
47
+ rating: nil
48
+ },
49
+ relationships: {
50
+ author: { data: { type: "authors", id: "1" } }
49
51
  }
50
52
  }
51
53
  ]
@@ -54,77 +54,93 @@ module ActiveModel
54
54
  data: [
55
55
  {
56
56
  id: "10",
57
- title: "Hello!!",
58
- body: "Hello, world!!",
59
57
  type: "posts",
60
- links: {
61
- comments: { linkage: [ { type: "comments", id: '1' }, { type: "comments", id: '2' } ] },
62
- blog: { linkage: { type: "blogs", id: "999" } },
63
- author: { linkage: { type: "authors", id: "1" } }
58
+ attributes: {
59
+ title: "Hello!!",
60
+ body: "Hello, world!!"
61
+ },
62
+ relationships: {
63
+ comments: { data: [ { type: "comments", id: '1' }, { type: "comments", id: '2' } ] },
64
+ blog: { data: { type: "blogs", id: "999" } },
65
+ author: { data: { type: "authors", id: "1" } }
64
66
  }
65
67
  },
66
68
  {
67
69
  id: "20",
68
- title: "New Post",
69
- body: "Body",
70
70
  type: "posts",
71
- links: {
72
- comments: { linkage: [] },
73
- blog: { linkage: { type: "blogs", id: "999" } },
74
- author: { linkage: { type: "authors", id: "2" } }
71
+ attributes: {
72
+ title: "New Post",
73
+ body: "Body"
74
+ },
75
+ relationships: {
76
+ comments: { data: [] },
77
+ blog: { data: { type: "blogs", id: "999" } },
78
+ author: { data: { type: "authors", id: "2" } }
75
79
  }
76
80
  }
77
81
  ],
78
82
  included: [
79
83
  {
80
84
  id: "1",
81
- body: "ZOMG A COMMENT",
82
85
  type: "comments",
83
- links: {
84
- post: { linkage: { type: "posts", id: "10" } },
85
- author: { linkage: nil }
86
+ attributes: {
87
+ body: "ZOMG A COMMENT"
88
+ },
89
+ relationships: {
90
+ post: { data: { type: "posts", id: "10" } },
91
+ author: { data: nil }
86
92
  }
87
93
  }, {
88
94
  id: "2",
89
- body: "ZOMG ANOTHER COMMENT",
90
95
  type: "comments",
91
- links: {
92
- post: { linkage: { type: "posts", id: "10" } },
93
- author: { linkage: nil }
96
+ attributes: {
97
+ body: "ZOMG ANOTHER COMMENT",
98
+ },
99
+ relationships: {
100
+ post: { data: { type: "posts", id: "10" } },
101
+ author: { data: nil }
94
102
  }
95
103
  }, {
96
104
  id: "1",
97
- name: "Steve K.",
98
105
  type: "authors",
99
- links: {
100
- posts: { linkage: [ { type: "posts", id: "10" }, { type: "posts", id: "30" } ] },
101
- roles: { linkage: [] },
102
- bio: { linkage: { type: "bios", id: "1" } }
106
+ attributes: {
107
+ name: "Steve K."
108
+ },
109
+ relationships: {
110
+ posts: { data: [ { type: "posts", id: "10" }, { type: "posts", id: "30" } ] },
111
+ roles: { data: [] },
112
+ bio: { data: { type: "bios", id: "1" } }
103
113
  }
104
114
  }, {
105
115
  id: "1",
106
- rating: nil,
107
116
  type: "bios",
108
- content: "AMS Contributor",
109
- links: {
110
- author: { linkage: { type: "authors", id: "1" } }
117
+ attributes: {
118
+ content: "AMS Contributor",
119
+ rating: nil
120
+ },
121
+ relationships: {
122
+ author: { data: { type: "authors", id: "1" } }
111
123
  }
112
124
  }, {
113
125
  id: "2",
114
- name: "Tenderlove",
115
126
  type: "authors",
116
- links: {
117
- posts: { linkage: [ { type: "posts", id:"20" } ] },
118
- roles: { linkage: [] },
119
- bio: { linkage: { type: "bios", id: "2" } }
127
+ attributes: {
128
+ name: "Tenderlove"
129
+ },
130
+ relationships: {
131
+ posts: { data: [ { type: "posts", id:"20" } ] },
132
+ roles: { data: [] },
133
+ bio: { data: { type: "bios", id: "2" } }
120
134
  }
121
135
  }, {
122
136
  id: "2",
123
- rating: nil,
124
137
  type: "bios",
125
- content: "Rails Contributor",
126
- links: {
127
- author: { linkage: { type: "authors", id: "2" } }
138
+ attributes: {
139
+ rating: nil,
140
+ content: "Rails Contributor",
141
+ },
142
+ relationships: {
143
+ author: { data: { type: "authors", id: "2" } }
128
144
  }
129
145
  }
130
146
  ]
@@ -148,31 +164,37 @@ module ActiveModel
148
164
  {
149
165
  id: "1",
150
166
  type: "authors",
151
- name: "Steve K.",
152
- links: {
153
- posts: { linkage: [ { type: "posts", id: "10"}, { type: "posts", id: "30" }] },
154
- roles: { linkage: [] },
155
- bio: { linkage: { type: "bios", id: "1" }}
167
+ attributes: {
168
+ name: "Steve K."
169
+ },
170
+ relationships: {
171
+ posts: { data: [ { type: "posts", id: "10"}, { type: "posts", id: "30" }] },
172
+ roles: { data: [] },
173
+ bio: { data: { type: "bios", id: "1" }}
156
174
  }
157
175
  }, {
158
176
  id: "10",
159
177
  type: "posts",
160
- title: "Hello!!",
161
- body: "Hello, world!!",
162
- links: {
163
- comments: { linkage: [ { type: "comments", id: "1"}, { type: "comments", id: "2" }] },
164
- blog: { linkage: { type: "blogs", id: "999" } },
165
- author: { linkage: { type: "authors", id: "1" } }
178
+ attributes: {
179
+ title: "Hello!!",
180
+ body: "Hello, world!!"
181
+ },
182
+ relationships: {
183
+ comments: { data: [ { type: "comments", id: "1"}, { type: "comments", id: "2" }] },
184
+ blog: { data: { type: "blogs", id: "999" } },
185
+ author: { data: { type: "authors", id: "1" } }
166
186
  }
167
187
  }, {
168
188
  id: "30",
169
189
  type: "posts",
170
- title: "Yet Another Post",
171
- body: "Body",
172
- links: {
173
- comments: { linkage: [] },
174
- blog: { linkage: { type: "blogs", id: "999" } },
175
- author: { linkage: { type: "authors", id: "1" } }
190
+ attributes: {
191
+ title: "Yet Another Post",
192
+ body: "Body"
193
+ },
194
+ relationships: {
195
+ comments: { data: [] },
196
+ blog: { data: { type: "blogs", id: "999" } },
197
+ author: { data: { type: "authors", id: "1" } }
176
198
  }
177
199
  }
178
200
  ]
@@ -181,21 +203,21 @@ module ActiveModel
181
203
  assert_equal expected, alt_adapter.serializable_hash[:included]
182
204
  end
183
205
 
184
- def test_ignore_model_namespace_for_linked_resource_type
206
+ def test_underscore_model_namespace_for_linked_resource_type
185
207
  spammy_post = Post.new(id: 123)
186
208
  spammy_post.related = [Spam::UnrelatedLink.new(id: 456)]
187
209
  serializer = SpammyPostSerializer.new(spammy_post)
188
210
  adapter = ActiveModel::Serializer::Adapter::JsonApi.new(serializer)
189
- links = adapter.serializable_hash[:data][:links]
211
+ relationships = adapter.serializable_hash[:data][:relationships]
190
212
  expected = {
191
213
  related: {
192
- linkage: [{
193
- type: 'unrelated_links',
214
+ data: [{
215
+ type: 'spam_unrelated_links',
194
216
  id: '456'
195
217
  }]
196
218
  }
197
219
  }
198
- assert_equal expected, links
220
+ assert_equal expected, relationships
199
221
  end
200
222
 
201
223
  def test_multiple_references_to_same_resource
@@ -208,18 +230,20 @@ module ActiveModel
208
230
  expected = [
209
231
  {
210
232
  id: "10",
211
- title: "Hello!!",
212
- body: "Hello, world!!",
213
233
  type: "posts",
214
- links: {
234
+ attributes: {
235
+ title: "Hello!!",
236
+ body: "Hello, world!!"
237
+ },
238
+ relationships: {
215
239
  comments: {
216
- linkage: [{type: "comments", id: "1"}, {type: "comments", id: "2"}]
240
+ data: [{type: "comments", id: "1"}, {type: "comments", id: "2"}]
217
241
  },
218
242
  blog: {
219
- linkage: {type: "blogs", id: "999"}
243
+ data: {type: "blogs", id: "999"}
220
244
  },
221
245
  author: {
222
- linkage: {type: "authors", id: "1"}
246
+ data: {type: "authors", id: "1"}
223
247
  }
224
248
  }
225
249
  }
@@ -239,12 +263,14 @@ module ActiveModel
239
263
  expected = {
240
264
  data: {
241
265
  id: "10",
242
- title: "Hello!!",
243
- body: "Hello, world!!",
244
266
  type: "posts",
245
- links: {
246
- comments: { linkage: [ { type: "comments", id: '1' }, { type: "comments", id: '2' } ] },
247
- author: { linkage: nil }
267
+ attributes: {
268
+ title: "Hello!!",
269
+ body: "Hello, world!!"
270
+ },
271
+ relationships: {
272
+ comments: { data: [ { type: "comments", id: '1' }, { type: "comments", id: '2' } ] },
273
+ author: { data: nil }
248
274
  }
249
275
  }
250
276
  }
@@ -25,7 +25,7 @@ module ActiveModel
25
25
  assert_equal([
26
26
  {id: 1, body: 'ZOMG A COMMENT'},
27
27
  {id: 2, body: 'ZOMG ANOTHER COMMENT'}
28
- ], @adapter.serializable_hash[:comments])
28
+ ], @adapter.serializable_hash[:post][:comments])
29
29
  end
30
30
  end
31
31
  end
@@ -31,7 +31,7 @@ module ActiveModel
31
31
 
32
32
  def test_create_adapter
33
33
  adapter = ActiveModel::Serializer::Adapter.create(@serializer)
34
- assert_equal ActiveModel::Serializer::Adapter::Json, adapter.class
34
+ assert_equal ActiveModel::Serializer::Adapter::FlattenJson, adapter.class
35
35
  end
36
36
 
37
37
  def test_create_adapter_with_override
@@ -24,6 +24,20 @@ module ActiveModel
24
24
 
25
25
  assert_equal serializers.last.custom_options[:some], :options
26
26
  end
27
+
28
+ def test_serializer_option_not_passed_to_each_serializer
29
+ serializers = ArraySerializer.new([@post], {serializer: PostSerializer}).to_a
30
+
31
+ refute serializers.first.custom_options.key?(:serializer)
32
+ end
33
+
34
+ def test_meta_and_meta_key_attr_readers
35
+ meta_content = {meta: "the meta", meta_key: "the meta key"}
36
+ @serializer = ArraySerializer.new([@comment, @post], meta_content)
37
+
38
+ assert_equal @serializer.meta, "the meta"
39
+ assert_equal @serializer.meta_key, "the meta key"
40
+ end
27
41
  end
28
42
  end
29
43
  end
@@ -1,4 +1,10 @@
1
1
  class Model
2
+ FILE_DIGEST = Digest::MD5.hexdigest(File.open(__FILE__).read)
3
+
4
+ def self.model_name
5
+ @_model_name ||= ActiveModel::Name.new(self)
6
+ end
7
+
2
8
  def initialize(hash={})
3
9
  @attributes = hash
4
10
  end
@@ -7,6 +13,10 @@ class Model
7
13
  "#{self.class.name.downcase}/#{self.id}-#{self.updated_at}"
8
14
  end
9
15
 
16
+ def cache_key_with_digest
17
+ "#{cache_key}/#{FILE_DIGEST}"
18
+ end
19
+
10
20
  def updated_at
11
21
  @attributes[:updated_at] ||= DateTime.now.to_time.to_i
12
22
  end
@@ -64,7 +74,7 @@ Author = Class.new(Model)
64
74
  Bio = Class.new(Model)
65
75
  Blog = Class.new(Model)
66
76
  Role = Class.new(Model)
67
- User = Class.new(Model)
77
+ User = Class.new(Model)
68
78
  Location = Class.new(Model)
69
79
  Place = Class.new(Model)
70
80
 
@@ -72,7 +82,7 @@ module Spam; end
72
82
  Spam::UnrelatedLink = Class.new(Model)
73
83
 
74
84
  PostSerializer = Class.new(ActiveModel::Serializer) do
75
- cache key:'post', expires_in: 0.1
85
+ cache key:'post', expires_in: 0.1, skip_digest: true
76
86
  attributes :id, :title, :body
77
87
 
78
88
  has_many :comments
@@ -99,7 +109,7 @@ SpammyPostSerializer = Class.new(ActiveModel::Serializer) do
99
109
  end
100
110
 
101
111
  CommentSerializer = Class.new(ActiveModel::Serializer) do
102
- cache expires_in: 1.day
112
+ cache expires_in: 1.day, skip_digest: true
103
113
  attributes :id, :body
104
114
 
105
115
  belongs_to :post
@@ -111,7 +121,7 @@ CommentSerializer = Class.new(ActiveModel::Serializer) do
111
121
  end
112
122
 
113
123
  AuthorSerializer = Class.new(ActiveModel::Serializer) do
114
- cache key:'writer'
124
+ cache key:'writer', skip_digest: true
115
125
  attributes :id, :name
116
126
 
117
127
  has_many :posts, embed: :ids
@@ -120,7 +130,7 @@ AuthorSerializer = Class.new(ActiveModel::Serializer) do
120
130
  end
121
131
 
122
132
  RoleSerializer = Class.new(ActiveModel::Serializer) do
123
- cache only: [:name]
133
+ cache only: [:name], skip_digest: true
124
134
  attributes :id, :name, :description, :slug
125
135
 
126
136
  def slug
@@ -137,7 +147,7 @@ LikeSerializer = Class.new(ActiveModel::Serializer) do
137
147
  end
138
148
 
139
149
  LocationSerializer = Class.new(ActiveModel::Serializer) do
140
- cache only: [:place]
150
+ cache only: [:place], skip_digest: true
141
151
  attributes :id, :lat, :lng
142
152
 
143
153
  belongs_to :place
@@ -154,13 +164,14 @@ PlaceSerializer = Class.new(ActiveModel::Serializer) do
154
164
  end
155
165
 
156
166
  BioSerializer = Class.new(ActiveModel::Serializer) do
157
- cache except: [:content]
167
+ cache except: [:content], skip_digest: true
158
168
  attributes :id, :content, :rating
159
169
 
160
170
  belongs_to :author
161
171
  end
162
172
 
163
173
  BlogSerializer = Class.new(ActiveModel::Serializer) do
174
+ cache key: 'blog'
164
175
  attributes :id, :name
165
176
 
166
177
  belongs_to :writer
@@ -178,6 +189,13 @@ AlternateBlogSerializer = Class.new(ActiveModel::Serializer) do
178
189
  attribute :name, key: :title
179
190
  end
180
191
 
192
+ CustomBlogSerializer = Class.new(ActiveModel::Serializer) do
193
+ attribute :id
194
+ attribute :special_attribute
195
+
196
+ has_many :articles
197
+ end
198
+
181
199
  CommentPreviewSerializer = Class.new(ActiveModel::Serializer) do
182
200
  attributes :id
183
201
 
@@ -204,3 +222,9 @@ end
204
222
  Spam::UnrelatedLinkSerializer = Class.new(ActiveModel::Serializer) do
205
223
  attributes :id
206
224
  end
225
+
226
+ RaiseErrorSerializer = Class.new(ActiveModel::Serializer) do
227
+ def json_key
228
+ raise StandardError, 'Intentional error for rescue_from test'
229
+ end
230
+ end
@@ -0,0 +1,24 @@
1
+ require 'test_helper'
2
+ # require 'active_model/serializer/railtie'
3
+
4
+ class ResourceGeneratorTest < Rails::Generators::TestCase
5
+ destination File.expand_path('../../../tmp/generators', __FILE__)
6
+ setup :prepare_destination, :copy_routes
7
+
8
+ tests Rails::Generators::ResourceGenerator
9
+ arguments %w(account)
10
+
11
+ def test_serializer_file_is_generated
12
+ run_generator
13
+
14
+ assert_file 'app/serializers/account_serializer.rb', /class AccountSerializer < ActiveModel::Serializer/
15
+ end
16
+
17
+ private
18
+
19
+ def copy_routes
20
+ config_dir = File.join(destination_root, 'config')
21
+ FileUtils.mkdir_p(config_dir)
22
+ File.write(File.join(config_dir, 'routes.rb'), 'Rails.application.routes.draw { }')
23
+ end
24
+ end