active_model_serializers_pg 0.0.1 → 0.0.2
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.
- checksums.yaml +4 -4
- data/README.md +43 -1
- data/Rakefile +16 -0
- data/lib/active_model_serializers/adapter/json_api_pg.rb +18 -3
- data/lib/active_model_serializers_pg.rb +5 -0
- data/lib/active_model_serializers_pg/collection_serializer.rb +117 -0
- data/lib/active_model_serializers_pg/version.rb +1 -1
- data/spec/serializer_spec.rb +111 -15
- data/spec/spec_helper.rb +35 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4bdfe8c6e1f9a0fbca6e444a7594474d43d9415008c86f6fe30964088fc8c1f7
|
4
|
+
data.tar.gz: 0e5a9f884cda2663bf2f36051ad42367381ea5f61798048cd4ae774c19c76265
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 44df1b79df5306e323a62c6fd0a6d0b52e6f2da6da8d6a6eb494fb440a9e09909ecd476cf563fa873a42bddedc40dbdc0efefb95cf13982ca69684b11c93050d
|
7
|
+
data.tar.gz: d08476c02adb38cb0978910b0d2448c0f09019ba52592132105612846e51d883d5ab0f26c6ad0f3eaf66c3757f3a93ab59831bfb6652459d47cdf8de37ba342d
|
data/README.md
CHANGED
@@ -6,7 +6,7 @@ This gem adds support for Rails 5 and AMS 0.10.
|
|
6
6
|
In addition we provide output in [JSON:API](https://jsonapi.org/) format.
|
7
7
|
(I'd like to add normal JSON output too, so let me know if that would be helpful to you.)
|
8
8
|
|
9
|
-
Building your JSON
|
9
|
+
Building your JSON in Postgres can reduce your response time 10 – 100x.
|
10
10
|
You skip instantiating thousands of Ruby objects (and garbage collecting them later),
|
11
11
|
and Postgres can generate the JSON far more quickly than AMS.
|
12
12
|
|
@@ -45,6 +45,16 @@ You could also turn it on for everything but then set `adapter: :json_api` for a
|
|
45
45
|
|
46
46
|
Note this gem also respects `ActiveModelSerializers.config.key_transform = :dash`, if you are using that.
|
47
47
|
|
48
|
+
### Supports
|
49
|
+
|
50
|
+
Here are some other details we support:
|
51
|
+
|
52
|
+
- `belongs_to`, `has_one`, and `has_many` associations.
|
53
|
+
- If you serialize an `enum` you get the string values, not integers.
|
54
|
+
- You can serialize an `alias`'d association.
|
55
|
+
- We preserve SQL ordering from a model's `default_scope`.
|
56
|
+
- We preserve SQL ordering attached to an association.
|
57
|
+
|
48
58
|
### Methods in Serializers and Models
|
49
59
|
|
50
60
|
If you are using methods to compute properties for your JSON responses
|
@@ -68,6 +78,26 @@ There is no instance of MyModel created so sql computed properties needs to be
|
|
68
78
|
a class method. Right now, this string is used as a SQL literal, so be sure to
|
69
79
|
*not* use untrusted values in the return value.
|
70
80
|
|
81
|
+
Similarly we also look for a `foo__sql` method
|
82
|
+
for relationships that aren't ActiveRecord associations.
|
83
|
+
It must return an `ActiveRecord::Relation` (not a `String`),
|
84
|
+
and we will run its SQL inside a `LEFT OUTER JOIN LATERAL`
|
85
|
+
(so it has access to the parent table). For example:
|
86
|
+
|
87
|
+
```ruby
|
88
|
+
class Book < ActiveRecord::Base
|
89
|
+
|
90
|
+
def essays_by_same_author
|
91
|
+
Essay.where(author_id: author_id)
|
92
|
+
end
|
93
|
+
|
94
|
+
def self.essays_by_same_author__sql
|
95
|
+
Essay.where("books.author_id = essays.author_id")
|
96
|
+
end
|
97
|
+
|
98
|
+
end
|
99
|
+
```
|
100
|
+
|
71
101
|
## Developing
|
72
102
|
|
73
103
|
To work on active\_model\_serializers\_pg locally, follow these steps:
|
@@ -89,6 +119,18 @@ Commands for building/releasing/installing:
|
|
89
119
|
* `rake install`
|
90
120
|
* `rake release`
|
91
121
|
|
122
|
+
### TODO
|
123
|
+
|
124
|
+
Here are things I'd like to support but don't yet:
|
125
|
+
|
126
|
+
- Use Arel to generate all the SQL.
|
127
|
+
- More support of custom scopes attached to associations.
|
128
|
+
- Add a non-JSON:API adapter, for traditional JSON output.
|
129
|
+
- Have all the tests verify they output the asme JSON as the built-in AMS serializers.
|
130
|
+
- Look at AMS's own tests for more features we should support.
|
131
|
+
- HABTM associations?
|
132
|
+
- `has_many through:` associations?
|
133
|
+
|
92
134
|
## Authors
|
93
135
|
|
94
136
|
Paul Jungwirth
|
data/Rakefile
CHANGED
@@ -82,6 +82,14 @@ namespace :db do
|
|
82
82
|
ActiveRecord::Base.connection.create_table :notes, force: true do |t|
|
83
83
|
t.string "name"
|
84
84
|
t.string "content"
|
85
|
+
t.integer "state", null: false, default: 0
|
86
|
+
t.datetime "created_at"
|
87
|
+
t.datetime "updated_at"
|
88
|
+
end
|
89
|
+
|
90
|
+
ActiveRecord::Base.connection.create_table :long_notes, force: true do |t|
|
91
|
+
t.string "name"
|
92
|
+
t.text "long_content"
|
85
93
|
t.datetime "created_at"
|
86
94
|
t.datetime "updated_at"
|
87
95
|
end
|
@@ -94,6 +102,14 @@ namespace :db do
|
|
94
102
|
t.datetime "updated_at"
|
95
103
|
end
|
96
104
|
|
105
|
+
ActiveRecord::Base.connection.create_table :long_tags, force: true do |t|
|
106
|
+
t.integer "long_note_id"
|
107
|
+
t.string "long_name"
|
108
|
+
t.boolean "popular"
|
109
|
+
t.datetime "created_at"
|
110
|
+
t.datetime "updated_at"
|
111
|
+
end
|
112
|
+
|
97
113
|
ActiveRecord::Base.connection.create_table :offers, force: true do |t|
|
98
114
|
t.integer "created_by_id"
|
99
115
|
t.integer "reviewed_by_id"
|
@@ -1,10 +1,13 @@
|
|
1
1
|
require 'active_model_serializers'
|
2
2
|
|
3
|
+
# We don't really need this
|
4
|
+
# because we try to inject our own CollectionSerializer,
|
5
|
+
# but keeping it lets us give a nice warning message
|
6
|
+
# instead of simply crashing:
|
3
7
|
module ActiveModel
|
4
8
|
class Serializer
|
5
9
|
class CollectionSerializer
|
6
10
|
def element_serializer
|
7
|
-
# TODO: This is probably not set every time
|
8
11
|
options[:serializer]
|
9
12
|
end
|
10
13
|
end
|
@@ -56,6 +59,15 @@ module ActiveModelSerializers
|
|
56
59
|
sql
|
57
60
|
end
|
58
61
|
|
62
|
+
def self.warn_about_collection_serializer
|
63
|
+
msg = "You are using an ordinary AMS CollectionSerializer with the json_api_pg adapter, which probably means Rails is pointlessly loading all your ActiveRecord instances *and* running the build JSON-building query in Postgres."
|
64
|
+
if Object.const_defined? 'Rails'
|
65
|
+
Rails.logger.warn msg
|
66
|
+
else
|
67
|
+
puts "WARN: #{msg}"
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
59
71
|
end
|
60
72
|
end
|
61
73
|
end
|
@@ -317,12 +329,15 @@ class JsonApiPgSql
|
|
317
329
|
# Make a JsonThing for everything,
|
318
330
|
# cached as the full_name:
|
319
331
|
|
320
|
-
# User.where is a Relation, but plain User is not:
|
332
|
+
# Watch out: User.where is a Relation, but plain User is not:
|
321
333
|
ar_class = ActiveRecord::Relation === base_relation ? base_relation.klass : base_relation
|
322
334
|
|
323
335
|
case base_serializer
|
324
336
|
when ActiveModel::Serializer::CollectionSerializer
|
325
|
-
|
337
|
+
ActiveModelSerializers::Adapter::JsonApiPg.warn_about_collection_serializer
|
338
|
+
base_serializer = base_serializer.element_serializer
|
339
|
+
@many = true
|
340
|
+
when ActiveModelSerializersPg::CollectionSerializer
|
326
341
|
base_serializer = base_serializer.element_serializer
|
327
342
|
@many = true
|
328
343
|
else
|
@@ -1 +1,6 @@
|
|
1
1
|
require 'active_model_serializers/adapter/json_api_pg'
|
2
|
+
require 'active_model_serializers_pg/collection_serializer'
|
3
|
+
|
4
|
+
# We have to inject our own CollectionSerializer to avoid materializing ActiveRecord::Relations.
|
5
|
+
# See more detailed notes in our class:
|
6
|
+
ActiveModel::Serializer.config.collection_serializer = ActiveModelSerializersPg::CollectionSerializer
|
@@ -0,0 +1,117 @@
|
|
1
|
+
# This is a near-verbatim copy of ActiveModel::Serializer::CollectionSerializer,
|
2
|
+
# but we patch the `initialize` method to avoid loading the ActiveRecord::Relation.
|
3
|
+
# It's still possible to load it if you call `each`, but we do it lazily.
|
4
|
+
# This is based on AMS 0.10.8. For each of updates we mark each of our changes
|
5
|
+
# with a `PATCHED` comment.
|
6
|
+
#
|
7
|
+
# It would be nicer to keep this class mostly empty
|
8
|
+
# and just delegate to an ActiveModel::Serializer::CollectionSerializer instance when needed,
|
9
|
+
# but then we'd still have to instantiate it eventually,
|
10
|
+
# any time we proxy a call (not just each),
|
11
|
+
# and that materializes the Relation.
|
12
|
+
# TODO: Is it possible to replace its `initialize` class? Or is that too wild even for Ruby?
|
13
|
+
module ActiveModelSerializersPg
|
14
|
+
class CollectionSerializer
|
15
|
+
include Enumerable
|
16
|
+
# PATCHED: implement this below so we don't need @serializers
|
17
|
+
# delegate :each, to: :@serializers
|
18
|
+
|
19
|
+
attr_reader :object, :root
|
20
|
+
|
21
|
+
def initialize(resources, options = {})
|
22
|
+
@object = resources
|
23
|
+
@options = options
|
24
|
+
@root = options[:root]
|
25
|
+
# PATCHED: We don't want to iterate unless we have to:
|
26
|
+
# @serializers = serializers_from_resources
|
27
|
+
end
|
28
|
+
|
29
|
+
# PATCH: Give ourselves access to the serializer for the individual elements:
|
30
|
+
def element_serializer
|
31
|
+
options[:serializer]
|
32
|
+
end
|
33
|
+
|
34
|
+
def success?
|
35
|
+
true
|
36
|
+
end
|
37
|
+
|
38
|
+
# @api private
|
39
|
+
def serializable_hash(adapter_options, options, adapter_instance)
|
40
|
+
options[:include_directive] ||= ActiveModel::Serializer.include_directive_from_options(adapter_options)
|
41
|
+
options[:cached_attributes] ||= ActiveModel::Serializer.cache_read_multi(self, adapter_instance, options[:include_directive])
|
42
|
+
serializers.map do |serializer|
|
43
|
+
serializer.serializable_hash(adapter_options, options, adapter_instance)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
# TODO: unify naming of root, json_key, and _type. Right now, a serializer's
|
48
|
+
# json_key comes from the root option or the object's model name, by default.
|
49
|
+
# But, if a dev defines a custom `json_key` method with an explicit value,
|
50
|
+
# we have no simple way to know that it is safe to call that instance method.
|
51
|
+
# (which is really a class property at this point, anyhow).
|
52
|
+
# rubocop:disable Metrics/CyclomaticComplexity
|
53
|
+
# Disabling cop since it's good to highlight the complexity of this method by
|
54
|
+
# including all the logic right here.
|
55
|
+
def json_key
|
56
|
+
return root if root
|
57
|
+
# 1. get from options[:serializer] for empty resource collection
|
58
|
+
key = object.empty? &&
|
59
|
+
(explicit_serializer_class = options[:serializer]) &&
|
60
|
+
explicit_serializer_class._type
|
61
|
+
# 2. get from first serializer instance in collection
|
62
|
+
key ||= (serializer = serializers.first) && serializer.json_key
|
63
|
+
# 3. get from collection name, if a named collection
|
64
|
+
key ||= object.respond_to?(:name) ? object.name && object.name.underscore : nil
|
65
|
+
# 4. key may be nil for empty collection and no serializer option
|
66
|
+
key &&= key.pluralize
|
67
|
+
# 5. fail if the key cannot be determined
|
68
|
+
key || fail(ArgumentError, 'Cannot infer root key from collection type. Please specify the root or each_serializer option, or render a JSON String')
|
69
|
+
end
|
70
|
+
# rubocop:enable Metrics/CyclomaticComplexity
|
71
|
+
|
72
|
+
def paginated?
|
73
|
+
ActiveModelSerializers.config.jsonapi_pagination_links_enabled &&
|
74
|
+
object.respond_to?(:current_page) &&
|
75
|
+
object.respond_to?(:total_pages) &&
|
76
|
+
object.respond_to?(:size)
|
77
|
+
end
|
78
|
+
|
79
|
+
# PATCHED: Add a replacement to `each` so we don't change the interface:
|
80
|
+
def each
|
81
|
+
Rails.logger.debug caller.join("\n")
|
82
|
+
Enumerator.new do |y|
|
83
|
+
serializers_from_resources.each do |ser|
|
84
|
+
y.yield ser
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
protected
|
90
|
+
|
91
|
+
attr_reader :serializers, :options
|
92
|
+
|
93
|
+
private
|
94
|
+
|
95
|
+
def serializers_from_resources
|
96
|
+
puts "options here"
|
97
|
+
pp options
|
98
|
+
serializer_context_class = options.fetch(:serializer_context_class, ActiveModel::Serializer)
|
99
|
+
object.map do |resource|
|
100
|
+
serializer_from_resource(resource, serializer_context_class, options)
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
def serializer_from_resource(resource, serializer_context_class, options)
|
105
|
+
serializer_class = options.fetch(:serializer) do
|
106
|
+
serializer_context_class.serializer_for(resource, namespace: options[:namespace])
|
107
|
+
end
|
108
|
+
|
109
|
+
if serializer_class.nil?
|
110
|
+
ActiveModelSerializers.logger.debug "No serializer found for resource: #{resource.inspect}"
|
111
|
+
throw :no_serializer
|
112
|
+
else
|
113
|
+
serializer_class.new(resource, options.except(:serializer))
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
data/spec/serializer_spec.rb
CHANGED
@@ -134,6 +134,68 @@ describe 'ArraySerializer' do
|
|
134
134
|
}.to_json
|
135
135
|
expect(json_data).to eq json_expected
|
136
136
|
end
|
137
|
+
|
138
|
+
end
|
139
|
+
|
140
|
+
context 'with dasherized keys and types' do
|
141
|
+
let(:relation) { LongNote.where(name: 'Title').first }
|
142
|
+
let(:controller) { LongNotesController.new }
|
143
|
+
let(:options) { { include: ['long_tags'] } }
|
144
|
+
|
145
|
+
before do
|
146
|
+
@note = LongNote.create long_content: 'Test', name: 'Title'
|
147
|
+
@tag = LongTag.create long_name: 'My tag', long_note: @note, popular: true
|
148
|
+
@old_key_setting = ActiveModelSerializers.config.key_transform
|
149
|
+
ActiveModelSerializers.config.key_transform = :dash
|
150
|
+
end
|
151
|
+
|
152
|
+
after do
|
153
|
+
ActiveModelSerializers.config.key_transform = @old_key_setting
|
154
|
+
end
|
155
|
+
|
156
|
+
it 'generates the proper json output' do
|
157
|
+
json_expected = {
|
158
|
+
data: {
|
159
|
+
id: @note.id.to_s,
|
160
|
+
type: 'long-notes',
|
161
|
+
attributes: { name: 'Title', 'long-content' => 'Test' },
|
162
|
+
relationships: { 'long-tags': { data: [{id: @tag.id.to_s, type: 'long-tags'}] } }
|
163
|
+
},
|
164
|
+
included: [
|
165
|
+
{
|
166
|
+
id: @tag.id.to_s,
|
167
|
+
type: 'long-tags',
|
168
|
+
attributes: { 'long-name' => 'My tag' },
|
169
|
+
relationships: { 'long-note' => { data: { id: @note.id.to_s, type: 'long-notes' } } },
|
170
|
+
}
|
171
|
+
]
|
172
|
+
}.to_json
|
173
|
+
expect(json_data).to eq json_expected
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
context 'with aliased association' do
|
178
|
+
let(:relation) { Tag.first }
|
179
|
+
let(:controller) { TagsController.new }
|
180
|
+
let(:options) { { serializer: TagWithAliasedNoteSerializer } }
|
181
|
+
|
182
|
+
before do
|
183
|
+
@note = Note.create content: 'Test', name: 'Title'
|
184
|
+
@tag = Tag.create name: 'My tag', note: @note, popular: true
|
185
|
+
end
|
186
|
+
|
187
|
+
it 'generates the proper json output' do
|
188
|
+
json_expected = {
|
189
|
+
data: {
|
190
|
+
id: @tag.id.to_s,
|
191
|
+
type: 'tags',
|
192
|
+
attributes: { name: 'My tag' },
|
193
|
+
relationships: { aliased_note: { data: {id: @note.id.to_s, type: 'notes'} } }
|
194
|
+
}
|
195
|
+
}.to_json
|
196
|
+
expect(json_data).to eq json_expected
|
197
|
+
end
|
198
|
+
|
137
199
|
end
|
138
200
|
|
139
201
|
context 'serialize single record with custom serializer' do
|
@@ -241,7 +303,21 @@ describe 'ArraySerializer' do
|
|
241
303
|
end
|
242
304
|
|
243
305
|
it 'does not instantiate ruby objects for relations' do
|
244
|
-
|
306
|
+
# It would be nice to do this instead:
|
307
|
+
#
|
308
|
+
# expect(relation).not_to receive(:load)
|
309
|
+
#
|
310
|
+
# or
|
311
|
+
#
|
312
|
+
# expect(relation).not_to receive(:records)
|
313
|
+
#
|
314
|
+
# But that causes an infinite loop because rspec works by raising an exception,
|
315
|
+
# and ActiveRecord notices that and wants to print an error message,
|
316
|
+
# calling `inspect` on the Relation, which tries to load the relation, which....
|
317
|
+
# The test still fails, but not in an articulate or informative way.
|
318
|
+
# TODO: We could probably write our own customer matcher to work around that,
|
319
|
+
# but this does the job for now:
|
320
|
+
expect(ActiveModelSerializers::Adapter::JsonApiPg).not_to receive(:warn_about_collection_serializer)
|
245
321
|
json_data
|
246
322
|
end
|
247
323
|
end
|
@@ -273,7 +349,7 @@ describe 'ArraySerializer' do
|
|
273
349
|
end
|
274
350
|
|
275
351
|
it 'does not instantiate ruby objects for relations' do
|
276
|
-
expect(
|
352
|
+
expect(ActiveModelSerializers::Adapter::JsonApiPg).not_to receive(:warn_about_collection_serializer)
|
277
353
|
json_data
|
278
354
|
end
|
279
355
|
end
|
@@ -307,12 +383,11 @@ describe 'ArraySerializer' do
|
|
307
383
|
end
|
308
384
|
|
309
385
|
it 'generates the proper json output for the serializer' do
|
310
|
-
puts json_data
|
311
386
|
expect(json_data).to eq @json_expected
|
312
387
|
end
|
313
388
|
|
314
389
|
it 'does not instantiate ruby objects for relations' do
|
315
|
-
expect(
|
390
|
+
expect(ActiveModelSerializers::Adapter::JsonApiPg).not_to receive(:warn_about_collection_serializer)
|
316
391
|
json_data
|
317
392
|
end
|
318
393
|
end
|
@@ -354,7 +429,7 @@ describe 'ArraySerializer' do
|
|
354
429
|
end
|
355
430
|
|
356
431
|
it 'does not instantiate ruby objects for relations' do
|
357
|
-
expect(
|
432
|
+
expect(ActiveModelSerializers::Adapter::JsonApiPg).not_to receive(:warn_about_collection_serializer)
|
358
433
|
json_data
|
359
434
|
end
|
360
435
|
end
|
@@ -373,7 +448,7 @@ describe 'ArraySerializer' do
|
|
373
448
|
end
|
374
449
|
|
375
450
|
it 'does not instantiate ruby objects for relations' do
|
376
|
-
expect(
|
451
|
+
expect(ActiveModelSerializers::Adapter::JsonApiPg).not_to receive(:warn_about_collection_serializer)
|
377
452
|
json_data
|
378
453
|
end
|
379
454
|
end
|
@@ -402,11 +477,40 @@ describe 'ArraySerializer' do
|
|
402
477
|
end
|
403
478
|
|
404
479
|
it 'does not instantiate ruby objects for relations' do
|
405
|
-
expect(
|
480
|
+
expect(ActiveModelSerializers::Adapter::JsonApiPg).not_to receive(:warn_about_collection_serializer)
|
406
481
|
json_data
|
407
482
|
end
|
408
483
|
end
|
409
484
|
|
485
|
+
context 'with enums' do
|
486
|
+
let(:relation) { Note.order(:id) }
|
487
|
+
let(:controller) { NotesController.new }
|
488
|
+
let(:options) { { each_serializer: NoteWithStateSerializer, fields: { note: [:name, :state] } } }
|
489
|
+
|
490
|
+
before do
|
491
|
+
@note1 = Note.create content: 'Test', name: 'Title 1', state: Note::Published
|
492
|
+
@note2 = Note.create content: 'Test', name: 'Title 2', state: Note::Deleted
|
493
|
+
end
|
494
|
+
|
495
|
+
it 'converts enum ints to strings' do
|
496
|
+
json_expected = {
|
497
|
+
data: [
|
498
|
+
{
|
499
|
+
id: @note1.id.to_s,
|
500
|
+
type: 'notes',
|
501
|
+
attributes: { name: 'Title 1', state: 'published' },
|
502
|
+
},
|
503
|
+
{
|
504
|
+
id: @note2.id.to_s,
|
505
|
+
type: 'notes',
|
506
|
+
attributes: { name: 'Title 2', state: 'deleted' },
|
507
|
+
}
|
508
|
+
]
|
509
|
+
}.to_json
|
510
|
+
expect(json_data).to eq json_expected
|
511
|
+
end
|
512
|
+
end
|
513
|
+
|
410
514
|
context 'support for include_[attrbute]' do
|
411
515
|
let(:relation) { User.all }
|
412
516
|
let(:controller) { UsersController.new }
|
@@ -565,15 +669,7 @@ describe 'ArraySerializer' do
|
|
565
669
|
|
566
670
|
pending 'obeys serializer option in has_many relationship' # Does AMS 0.10 still support this?
|
567
671
|
|
568
|
-
pending 'obeys overall :include option'
|
569
|
-
|
570
672
|
pending 'obeys :include option in serializer association' # Does AMS 0.10 still support this?
|
571
673
|
|
572
|
-
pending 'figures out aliased associations'
|
573
|
-
|
574
|
-
pending 'makes dasherized keys and types'
|
575
|
-
|
576
|
-
pending 'serializes enums'
|
577
|
-
|
578
674
|
pending 'uses __sql methods for relationships'
|
579
675
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -61,6 +61,10 @@ class Note < ActiveRecord::Base
|
|
61
61
|
has_many :sorted_tags
|
62
62
|
has_many :custom_sorted_tags, lambda { order(:name) }, class_name: 'Tag'
|
63
63
|
has_many :popular_tags, lambda { where(popular: true) }, class_name: 'Tag'
|
64
|
+
Draft = :draft
|
65
|
+
Published = :published
|
66
|
+
Deleted = :deleted
|
67
|
+
enum state: [Draft, Published, Deleted]
|
64
68
|
end
|
65
69
|
|
66
70
|
class NotesController < TestController; end
|
@@ -70,6 +74,22 @@ class NoteSerializer < ActiveModel::Serializer
|
|
70
74
|
has_many :tags
|
71
75
|
end
|
72
76
|
|
77
|
+
class NoteWithStateSerializer < ActiveModel::Serializer
|
78
|
+
attributes :content, :name, :state
|
79
|
+
has_many :tags
|
80
|
+
end
|
81
|
+
|
82
|
+
class LongNote < ActiveRecord::Base
|
83
|
+
has_many :long_tags
|
84
|
+
end
|
85
|
+
|
86
|
+
class LongNotesController < TestController; end
|
87
|
+
|
88
|
+
class LongNoteSerializer < ActiveModel::Serializer
|
89
|
+
attributes :long_content, :name
|
90
|
+
has_many :long_tags
|
91
|
+
end
|
92
|
+
|
73
93
|
class ShortTagSerializer < ActiveModel::Serializer
|
74
94
|
attributes :id, :name
|
75
95
|
end
|
@@ -105,6 +125,7 @@ end
|
|
105
125
|
|
106
126
|
class Tag < ActiveRecord::Base
|
107
127
|
belongs_to :note
|
128
|
+
alias :aliased_note :note
|
108
129
|
end
|
109
130
|
|
110
131
|
class SortedTag < Tag
|
@@ -112,6 +133,15 @@ class SortedTag < Tag
|
|
112
133
|
default_scope { order(:name) }
|
113
134
|
end
|
114
135
|
|
136
|
+
class LongTag < ActiveRecord::Base
|
137
|
+
belongs_to :long_note
|
138
|
+
end
|
139
|
+
|
140
|
+
class LongTagSerializer < ActiveModel::Serializer
|
141
|
+
attributes :long_name
|
142
|
+
belongs_to :long_note
|
143
|
+
end
|
144
|
+
|
115
145
|
class TagWithNote < Tag
|
116
146
|
belongs_to :note
|
117
147
|
default_scope { joins(:note) }
|
@@ -129,6 +159,11 @@ class TagWithNoteSerializer < ActiveModel::Serializer
|
|
129
159
|
has_one :note
|
130
160
|
end
|
131
161
|
|
162
|
+
class TagWithAliasedNoteSerializer < ActiveModel::Serializer
|
163
|
+
attributes :name
|
164
|
+
has_one :aliased_note
|
165
|
+
end
|
166
|
+
|
132
167
|
class User < ActiveRecord::Base
|
133
168
|
has_many :offers, foreign_key: :created_by_id, inverse_of: :created_by
|
134
169
|
has_many :reviewed_offers, foreign_key: :reviewed_by_id, inverse_of: :reviewed_by, class_name: 'Offer'
|
@@ -172,7 +207,6 @@ DatabaseCleaner.strategy = :deletion
|
|
172
207
|
RSpec.configure do |config|
|
173
208
|
config.before(:each) do
|
174
209
|
DatabaseCleaner.start
|
175
|
-
# FactoryBot.lint
|
176
210
|
end
|
177
211
|
|
178
212
|
config.after(:each) do
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: active_model_serializers_pg
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Paul A. Jungwirth
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-10-
|
11
|
+
date: 2019-10-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: active_model_serializers
|
@@ -170,6 +170,7 @@ files:
|
|
170
170
|
- gemfiles/Gemfile.activerecord-5.2.x
|
171
171
|
- lib/active_model_serializers/adapter/json_api_pg.rb
|
172
172
|
- lib/active_model_serializers_pg.rb
|
173
|
+
- lib/active_model_serializers_pg/collection_serializer.rb
|
173
174
|
- lib/active_model_serializers_pg/version.rb
|
174
175
|
- spec/serializer_spec.rb
|
175
176
|
- spec/spec_helper.rb
|