oj_serializers 2.0.1 → 2.0.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +20 -0
- data/README.md +65 -12
- data/lib/oj_serializers/compat.rb +46 -0
- data/lib/oj_serializers/serializer.rb +3 -2
- data/lib/oj_serializers/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f9532d127e357231931f57cda2531743fe4064d0f9e0371cb2aac81a39dedb35
|
4
|
+
data.tar.gz: 8465a8f1f8e39fb48cd07a6c6156ff744f7e094a2985e01a1a13445957f2b3f0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 176c981929972198d8cbaf9548cc9238b60f51010fbd33415a70c25ed8f167885e8cfa494820cc668a03eb9cf96664bb40ba4b2cc69efc4e229763e621aa7190
|
7
|
+
data.tar.gz: d0d7ea0e5fc50b993b7439e50be0c59f6da26c23ac542c69838b5c145197d598186ae162ce9bc82711942b8e94631acb99acfe4739e04b1e25e28e1f6b70f260
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,23 @@
|
|
1
|
+
## Oj Serializers 2.0.3 (2023-04-19)
|
2
|
+
|
3
|
+
### Features ✨
|
4
|
+
|
5
|
+
- [Allow `key` and `unless` in AMS-compat mode](https://github.com/ElMassimo/oj_serializers/commit/5050710e199651cc2c0e9d9d6395f2c2ac9b1875)
|
6
|
+
|
7
|
+
### Fixes 🐞
|
8
|
+
|
9
|
+
- [Allow using `active_model_serializers` in associations](https://github.com/ElMassimo/oj_serializers/commit/501ed4014b564e6f103d2f52d15832fe6706d6a8)
|
10
|
+
|
11
|
+
## Oj Serializers 2.0.2 (2023-04-02)
|
12
|
+
|
13
|
+
### Features ✨
|
14
|
+
|
15
|
+
- [Automatically remove `?` when using `transform_keys :camelize`](https://github.com/ElMassimo/oj_serializers/commit/79758a0)
|
16
|
+
|
17
|
+
### Fixes 🐞
|
18
|
+
|
19
|
+
- [Error when defining attributes with options](https://github.com/ElMassimo/oj_serializers/commit/680ab47)
|
20
|
+
|
1
21
|
## Oj Serializers 2.0.1 (2023-04-02)
|
2
22
|
|
3
23
|
### Features ✨
|
data/README.md
CHANGED
@@ -22,6 +22,8 @@ Faster JSON serializers for Ruby, built on top of the powerful [`oj`][oj] librar
|
|
22
22
|
[sugar]: https://github.com/ElMassimo/oj_serializers/blob/main/lib/oj_serializers/sugar.rb#L14
|
23
23
|
[migration guide]: https://github.com/ElMassimo/oj_serializers/blob/main/MIGRATION_GUIDE.md
|
24
24
|
[design]: https://github.com/ElMassimo/oj_serializers#design-
|
25
|
+
[associations]: https://github.com/ElMassimo/oj_serializers#associations-
|
26
|
+
[compose]: https://github.com/ElMassimo/oj_serializers#composing-serializers-
|
25
27
|
[raw_json]: https://github.com/ohler55/oj/issues/542
|
26
28
|
[trailing_commas]: https://maximomussini.com/posts/trailing-commas/
|
27
29
|
[render dsl]: https://github.com/ElMassimo/oj_serializers#render-dsl-
|
@@ -29,6 +31,7 @@ Faster JSON serializers for Ruby, built on top of the powerful [`oj`][oj] librar
|
|
29
31
|
[Discussion]: https://github.com/ElMassimo/oj_serializers/discussions
|
30
32
|
[TypeScript]: https://www.typescriptlang.org/
|
31
33
|
[types_from_serializers]: https://github.com/ElMassimo/types_from_serializers
|
34
|
+
[inheritance]: https://github.com/ElMassimo/types_from_serializers/blob/main/playground/vanilla/app/serializers/song_with_videos_serializer.rb#L1
|
32
35
|
|
33
36
|
## Why? 🤔
|
34
37
|
|
@@ -41,12 +44,12 @@ Learn more about [how this library achieves its performance][design].
|
|
41
44
|
|
42
45
|
## Features ⚡️
|
43
46
|
|
44
|
-
-
|
47
|
+
- Intuitive declaration syntax, supporting mixins and inheritance
|
45
48
|
- Reduced [memory allocation][benchmarks] and [improved performance][benchmarks]
|
46
|
-
-
|
49
|
+
- Generate [TypeScript interfaces automatically][types_from_serializers]
|
50
|
+
- Support for [`has_one`][associations] and [`has_many`][associations], compose with [`flat_one`][compose]
|
47
51
|
- Useful development checks to avoid typos and mistakes
|
48
|
-
-
|
49
|
-
- [Generate TypeScript interfaces automatically][types_from_serializers]
|
52
|
+
- [Migrate easily from Active Model Serializers][migration guide]
|
50
53
|
|
51
54
|
## Installation 💿
|
52
55
|
|
@@ -155,6 +158,24 @@ class AlbumsController < ApplicationController
|
|
155
158
|
end
|
156
159
|
```
|
157
160
|
|
161
|
+
<details>
|
162
|
+
<summary>Active Model Serializers style</summary>
|
163
|
+
|
164
|
+
```ruby
|
165
|
+
require "oj_serializers/sugar" # In an initializer
|
166
|
+
|
167
|
+
class AlbumsController < ApplicationController
|
168
|
+
def show
|
169
|
+
render json: album, serializer: AlbumSerializer
|
170
|
+
end
|
171
|
+
|
172
|
+
def index
|
173
|
+
render json: albums, root: :albums, each_serializer: AlbumSerializer
|
174
|
+
end
|
175
|
+
end
|
176
|
+
```
|
177
|
+
</details>
|
178
|
+
|
158
179
|
## Rendering 🖨
|
159
180
|
|
160
181
|
Use `one` to serialize objects, and `many` to serialize enumerables:
|
@@ -170,7 +191,7 @@ Serializers can be rendered arrays, hashes, or even inside `ActiveModel::Seriali
|
|
170
191
|
by using a method in the serializer, making it very easy to combine with other
|
171
192
|
libraries and migrate incrementally.
|
172
193
|
|
173
|
-
|
194
|
+
`render` is a shortcut for `one` and `many`:
|
174
195
|
|
175
196
|
```ruby
|
176
197
|
render json: {
|
@@ -378,6 +399,43 @@ It's easy for the backend and the frontend to become out of sync. Traditionally,
|
|
378
399
|
|
379
400
|
As a result, it's posible to easily detect mismatches between the backend and the frontend, as well as make the fields more discoverable and provide great autocompletion in the frontend, without having to manually write the types.
|
380
401
|
|
402
|
+
### Composing serializers 🧱
|
403
|
+
|
404
|
+
There are three options to [compose serializers](https://github.com/ElMassimo/oj_serializers/discussions/10#discussioncomment-5523921): [inheritance], mixins, and `flat_one`.
|
405
|
+
|
406
|
+
Use `flat_one` to include all attributes from a different serializer:
|
407
|
+
|
408
|
+
```ruby
|
409
|
+
class AttachmentSerializer < BaseSerializer
|
410
|
+
identifier
|
411
|
+
|
412
|
+
class BlobSerializer < BaseSerializer
|
413
|
+
attributes :filename, :byte_size, :content_type, :created_at
|
414
|
+
end
|
415
|
+
|
416
|
+
flat_one :blob, serializer: BlobSerializer
|
417
|
+
end
|
418
|
+
```
|
419
|
+
|
420
|
+
Think of it as `has_one` without a "root", all the attributes are added directly.
|
421
|
+
|
422
|
+
<details>
|
423
|
+
<summary>Example Output</summary>
|
424
|
+
|
425
|
+
```ruby
|
426
|
+
{
|
427
|
+
id: 5,
|
428
|
+
filename: "image.jpg,
|
429
|
+
byte_size: 256074,
|
430
|
+
content_type: "image/jpeg",
|
431
|
+
created_at: "2022-08-04T17:25:12.637-07:00",
|
432
|
+
}
|
433
|
+
```
|
434
|
+
</details>
|
435
|
+
|
436
|
+
This is especially convenient when using [`types_from_serializers`][types_from_serializers],
|
437
|
+
as it enables automatic type inference for the included attributes.
|
438
|
+
|
381
439
|
### Memoization & local state
|
382
440
|
|
383
441
|
Serializers are designed to be stateless so that an instanced can be reused, but
|
@@ -480,10 +538,8 @@ end
|
|
480
538
|
This will change the default shortcuts (`render`, `one`, `one_if`, and `many`),
|
481
539
|
so that the serializer writes directly to JSON instead of returning a Hash.
|
482
540
|
|
483
|
-
|
484
|
-
|
485
|
-
> This was the default behavior in `oj_serializers` v1, but was replaced with
|
486
|
-
`default_format :hash` in v2.
|
541
|
+
Even when using this mode, you can still use rendered values inside arrays,
|
542
|
+
hashes, and other serializers, thanks to [the `raw_json` extensions][raw_json].
|
487
543
|
|
488
544
|
<details>
|
489
545
|
<summary>Example Output</summary>
|
@@ -569,9 +625,6 @@ so that the serializer writes directly to JSON instead of returning a Hash.
|
|
569
625
|
```
|
570
626
|
</details>
|
571
627
|
|
572
|
-
Even when using this mode, you can still use rendered values inside arrays,
|
573
|
-
hashes, and other serializers, thanks to [the `raw_json` extensions][raw_json].
|
574
|
-
|
575
628
|
## Design 📐
|
576
629
|
|
577
630
|
Unlike `ActiveModel::Serializer`, which builds a Hash that then gets encoded to
|
@@ -14,7 +14,53 @@ class ActiveModel::Serializer
|
|
14
14
|
def self.many(array, options = nil)
|
15
15
|
array.map { |object| new(object, options) }
|
16
16
|
end
|
17
|
+
|
18
|
+
# OjSerializer: Used internally to write a single object association in :hash mode.
|
19
|
+
#
|
20
|
+
# Returns nothing.
|
21
|
+
def self.one_as_hash(object)
|
22
|
+
new(object)
|
23
|
+
end
|
24
|
+
|
25
|
+
# OjSerializer: Used internally to write an association in :hash mode.
|
26
|
+
#
|
27
|
+
# Returns nothing.
|
28
|
+
def self.many_as_hash(array)
|
29
|
+
array.map { |object| new(object) }
|
30
|
+
end
|
31
|
+
|
32
|
+
# OjSerializer: Used internally to write a single object association in :json mode.
|
33
|
+
#
|
34
|
+
# Returns nothing.
|
35
|
+
def self.write_one(writer, object)
|
36
|
+
writer.push_value(new(object))
|
37
|
+
end
|
38
|
+
|
39
|
+
# OjSerializer: Used internally to write an association in :json mode.
|
40
|
+
#
|
41
|
+
# Returns nothing.
|
42
|
+
def self.write_many(writer, array)
|
43
|
+
writer.push_array
|
44
|
+
array.each do |object|
|
45
|
+
write_one(writer, object)
|
46
|
+
end
|
47
|
+
writer.pop
|
48
|
+
end
|
49
|
+
|
50
|
+
module OjOptionsCompat
|
51
|
+
def add_attribute(value_from, key: nil, **options)
|
52
|
+
options[:as] ||= key if key
|
53
|
+
|
54
|
+
if (unless_proc = options.delete(:unless))
|
55
|
+
options[:if] = -> { !instance_exec(&unless_proc) }
|
56
|
+
end
|
57
|
+
|
58
|
+
super(value_from, **options)
|
59
|
+
end
|
60
|
+
end
|
17
61
|
end
|
18
62
|
|
19
63
|
require 'oj_serializers'
|
20
64
|
require 'oj_serializers/sugar'
|
65
|
+
|
66
|
+
Oj::Serializer.singleton_class.prepend(ActiveModel::Serializer::OjOptionsCompat)
|
@@ -126,7 +126,7 @@ protected
|
|
126
126
|
# This setting is inherited from parent classes.
|
127
127
|
def transform_keys(strategy = nil, &block)
|
128
128
|
transformer = case (strategy ||= block)
|
129
|
-
when :camelize, :camel_case then ->(key) { key.camelize(:lower) }
|
129
|
+
when :camelize, :camel_case then ->(key) { key.camelize(:lower).chomp('?') }
|
130
130
|
when :none then nil
|
131
131
|
when Symbol then strategy.to_proc
|
132
132
|
when Proc then strategy
|
@@ -376,7 +376,7 @@ protected
|
|
376
376
|
#
|
377
377
|
# See ./benchmarks/document_benchmark.rb
|
378
378
|
def mongo_attributes(*attr_names, **options)
|
379
|
-
identifier(:_id, as: :id, attribute: :mongoid, **options) if attr_names.delete(:id)
|
379
|
+
identifier(:_id, as: :id, attribute: :mongoid, **options.slice(:if)) if attr_names.delete(:id)
|
380
380
|
attributes(*attr_names, **options, attribute: :mongoid)
|
381
381
|
end
|
382
382
|
|
@@ -392,6 +392,7 @@ protected
|
|
392
392
|
|
393
393
|
methods_with_options.each do |attr_name, options|
|
394
394
|
options = { as: options } if options.is_a?(Symbol)
|
395
|
+
options[:attribute] ||= attr_options[:attribute]
|
395
396
|
add_attribute(attr_name, **options)
|
396
397
|
end
|
397
398
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: oj_serializers
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0.
|
4
|
+
version: 2.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Maximo Mussini
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-04-
|
11
|
+
date: 2023-04-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: oj
|