userializer 0.2.0 → 0.3.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/.github/pull_request_template.md +28 -0
- data/.github/workflows/ci.yml +25 -0
- data/README.md +27 -0
- data/lib/userializer/base_serializer.rb +10 -4
- data/lib/userializer/composite_serializer.rb +78 -0
- data/lib/userializer/has_many.rb +8 -2
- data/lib/userializer/has_one.rb +1 -1
- data/lib/userializer/version.rb +1 -1
- data/lib/userializer.rb +1 -0
- metadata +6 -4
- data/.circleci/config.yml +0 -18
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 39db10c77bd519fffda4b6e6c7e613bc1105a951ab39e677dd8d1aaa0aa6f6b0
|
4
|
+
data.tar.gz: 5327aa7eb5e03f5abe504e4dde6d4e619df810af3802e896e28a72e9edc5c21f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1fcc67f9270e9c8359dc4488eaf11684fcb952f563a64d41f90cae3d83c1ff31a5c271c2247bc538fa3b5877241d3a7f769a32100c9e04ed9cb327caa15fa92f
|
7
|
+
data.tar.gz: 982d8a1495d2c3a6eb83b498b79a6e9d40910f05226b3e4d14a0d5ab1100d04c4145c1d7e14ccd083f5329cf380089300e131848b7d9d2e6692f498793057b91
|
@@ -0,0 +1,28 @@
|
|
1
|
+
### What does this PR do?
|
2
|
+
|
3
|
+
<!-- A brief description of the context of this pull request and its purpose. -->
|
4
|
+
|
5
|
+
### What are the observable changes?
|
6
|
+
<!-- This question could be adequate with multiple use cases, for example: -->
|
7
|
+
|
8
|
+
<!-- Frontend: explain the feature created / updated, give instructions telling how to see the change in staging -->
|
9
|
+
<!-- Performance: what metric should be impacted, link to the right graphana dashboard for exemple -->
|
10
|
+
<!-- Bug: a given issue trail on sentry should stop happening -->
|
11
|
+
<!-- Feature: Implements X thrift service / Z HTTP REST API added, provide instructions on how leverage your feature from staging or your workstation -->
|
12
|
+
|
13
|
+
### Good PR checklist
|
14
|
+
|
15
|
+
- [ ] Title makes sense
|
16
|
+
- [ ] Is against the correct branch
|
17
|
+
- [ ] Only addresses one issue
|
18
|
+
- [ ] Properly assigned
|
19
|
+
- [ ] Added/updated tests
|
20
|
+
- [ ] Added/updated documentation
|
21
|
+
- [ ] Properly labeled
|
22
|
+
|
23
|
+
### Additional Notes
|
24
|
+
|
25
|
+
<!--
|
26
|
+
You can add anything you want here, an explanation on the way you built your implementation,
|
27
|
+
precisions on the origin of the bug, gotchas you need to mention.
|
28
|
+
-->
|
@@ -0,0 +1,25 @@
|
|
1
|
+
name: ci
|
2
|
+
|
3
|
+
on:
|
4
|
+
push:
|
5
|
+
branches:
|
6
|
+
- master
|
7
|
+
pull_request:
|
8
|
+
|
9
|
+
jobs:
|
10
|
+
test:
|
11
|
+
name: Run Tests
|
12
|
+
runs-on: ubuntu-20.04
|
13
|
+
strategy:
|
14
|
+
matrix:
|
15
|
+
ruby: [2.7, 3.0.3]
|
16
|
+
steps:
|
17
|
+
- name: Checkout
|
18
|
+
uses: actions/checkout@v2
|
19
|
+
- name: Install Ruby
|
20
|
+
uses: ruby/setup-ruby@v1
|
21
|
+
with:
|
22
|
+
ruby-version: ${{ matrix.ruby }}
|
23
|
+
bundler-cache: true
|
24
|
+
- name: Run the Test Suite
|
25
|
+
run: bundle exec rspec --color --require spec_helper --format progress spec
|
data/README.md
CHANGED
@@ -167,6 +167,33 @@ different situations:
|
|
167
167
|
}
|
168
168
|
```
|
169
169
|
|
170
|
+
### CompositeSerializer
|
171
|
+
|
172
|
+
Imagine you have a compound of different data that you want to return to the same payload.
|
173
|
+
For example, you have an **array** of a `Foo` class and a `Bar` value to return.
|
174
|
+
You can use a `CompositeSerializer` to serialize both.
|
175
|
+
|
176
|
+
```ruby
|
177
|
+
array_foo = [Foo.new, Foo.new]
|
178
|
+
bar = Bar.new
|
179
|
+
|
180
|
+
CompositeSerializer.new(
|
181
|
+
{ key_foo: array_foo, key_bar: bar },
|
182
|
+
each_serializer: { key_foo: FooCustomSerializer },
|
183
|
+
serializer: { key_bar: BarSerializer },
|
184
|
+
root: { key_foo: :foo_root, key_bar: :bar_root }
|
185
|
+
).to_json
|
186
|
+
```
|
187
|
+
|
188
|
+
this will render:
|
189
|
+
|
190
|
+
```json
|
191
|
+
{
|
192
|
+
"foo_root": [{... foo1 attributes ...}, {... foo2 attributes ...}],
|
193
|
+
"bar_root": {... bar attributes ...}
|
194
|
+
}
|
195
|
+
```
|
196
|
+
|
170
197
|
## Development
|
171
198
|
|
172
199
|
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
@@ -45,6 +45,7 @@ module USerializer
|
|
45
45
|
@opts = opts
|
46
46
|
@meta = opts[:meta]
|
47
47
|
@except = Set.new([opts[:except]].flatten.compact)
|
48
|
+
@only = Set.new([opts[:only]].flatten.compact)
|
48
49
|
|
49
50
|
@root_key = (opts[:root] || ActiveSupport::Inflector.underscore(
|
50
51
|
obj.class.name
|
@@ -99,15 +100,20 @@ module USerializer
|
|
99
100
|
private
|
100
101
|
|
101
102
|
def attributes
|
102
|
-
@attributes ||= (self.class.attrs || {}).values.
|
103
|
-
|
103
|
+
@attributes ||= (self.class.attrs || {}).values.select do |attr|
|
104
|
+
allow?(attr.key)
|
104
105
|
end
|
105
106
|
end
|
106
107
|
|
107
108
|
def relations
|
108
|
-
@relations ||= (self.class.relations || {}).values.
|
109
|
-
|
109
|
+
@relations ||= (self.class.relations || {}).values.select do |rel|
|
110
|
+
allow?(rel.key)
|
110
111
|
end
|
111
112
|
end
|
113
|
+
|
114
|
+
def allow?(key)
|
115
|
+
return @only.include?(key) if @only.any?
|
116
|
+
!@except.include?(key)
|
117
|
+
end
|
112
118
|
end
|
113
119
|
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
require 'oj'
|
2
|
+
|
3
|
+
module USerializer
|
4
|
+
class CompositeObject
|
5
|
+
def initialize(obj, opts = {})
|
6
|
+
@obj = obj
|
7
|
+
@opts = opts
|
8
|
+
@root_key = opts[:root].to_sym
|
9
|
+
serializer = opts[:serializer]
|
10
|
+
@serializer = if serializer.is_a?(Proc)
|
11
|
+
serializer
|
12
|
+
elsif serializer
|
13
|
+
proc { serializer }
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def merge_root(res, opts)
|
18
|
+
serializer(@obj, opts).merge_root(res, @root_key, true, opts)
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def serializer(obj, opts)
|
24
|
+
return @serializer.call(obj, opts).new(obj, @opts) if @serializer
|
25
|
+
return obj.serialize if obj.respond_to?(:serialize)
|
26
|
+
|
27
|
+
USerializer.infered_serializer_class(obj.class).new(obj, @opts)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
class CompositeSerializer
|
32
|
+
def initialize(objs, opts = {})
|
33
|
+
@opts = opts
|
34
|
+
@objs = compose_objs(objs)
|
35
|
+
end
|
36
|
+
|
37
|
+
def merge_root(res, opts)
|
38
|
+
@objs.each do |obj|
|
39
|
+
obj.merge_root(res, opts)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def to_hash
|
44
|
+
res = {}
|
45
|
+
|
46
|
+
merge_root(res, @opts)
|
47
|
+
res
|
48
|
+
end
|
49
|
+
|
50
|
+
def serialize(*_args)
|
51
|
+
to_hash
|
52
|
+
end
|
53
|
+
|
54
|
+
def to_json(*_args)
|
55
|
+
Oj.dump(to_hash, mode: :compat)
|
56
|
+
end
|
57
|
+
|
58
|
+
private
|
59
|
+
|
60
|
+
def compose_objs(objs)
|
61
|
+
objs.map do |(key, obj)|
|
62
|
+
opts = options_for(key)
|
63
|
+
|
64
|
+
if obj.is_a? Enumerable
|
65
|
+
ArraySerializer.new(obj, opts)
|
66
|
+
else
|
67
|
+
CompositeObject.new(obj, opts)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def options_for(key)
|
73
|
+
@opts.reduce({}) do |acc, (opt_key, values)|
|
74
|
+
acc.merge(opt_key.to_sym => values[key.to_sym])
|
75
|
+
end.compact.merge(root: key) { |_, x, y| x || y }
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
data/lib/userializer/has_many.rb
CHANGED
@@ -6,7 +6,7 @@ module USerializer
|
|
6
6
|
@key = key
|
7
7
|
|
8
8
|
@opts = opts
|
9
|
-
@
|
9
|
+
@ids_key = opts[:ids_key] || build_ids_key(key)
|
10
10
|
|
11
11
|
@embed_key = opts[:embed_key] || :id
|
12
12
|
@conditional_block = opts[:if] || proc { true }
|
@@ -15,7 +15,7 @@ module USerializer
|
|
15
15
|
def merge_attributes(res, ser, opts)
|
16
16
|
return unless @conditional_block.call(ser.object, opts)
|
17
17
|
|
18
|
-
res[@
|
18
|
+
res[@ids_key] = (entities(ser) || []).compact.map do |obj|
|
19
19
|
obj.nil? ? nil : obj.send(@embed_key)
|
20
20
|
end.compact
|
21
21
|
end
|
@@ -34,5 +34,11 @@ module USerializer
|
|
34
34
|
|
35
35
|
obj.send(@opts[:scope])
|
36
36
|
end
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
def build_ids_key(key)
|
41
|
+
"#{ActiveSupport::Inflector.singularize(key)}_ids".to_sym
|
42
|
+
end
|
37
43
|
end
|
38
44
|
end
|
data/lib/userializer/has_one.rb
CHANGED
data/lib/userializer/version.rb
CHANGED
data/lib/userializer.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: userializer
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2
|
4
|
+
version: 0.3.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Alexis Montagne
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-05-25 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -87,7 +87,8 @@ executables: []
|
|
87
87
|
extensions: []
|
88
88
|
extra_rdoc_files: []
|
89
89
|
files:
|
90
|
-
- ".
|
90
|
+
- ".github/pull_request_template.md"
|
91
|
+
- ".github/workflows/ci.yml"
|
91
92
|
- ".gitignore"
|
92
93
|
- ".rspec"
|
93
94
|
- ".travis.yml"
|
@@ -100,6 +101,7 @@ files:
|
|
100
101
|
- lib/userializer/array_serializer.rb
|
101
102
|
- lib/userializer/attribute.rb
|
102
103
|
- lib/userializer/base_serializer.rb
|
104
|
+
- lib/userializer/composite_serializer.rb
|
103
105
|
- lib/userializer/has_many.rb
|
104
106
|
- lib/userializer/has_one.rb
|
105
107
|
- lib/userializer/version.rb
|
@@ -122,7 +124,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
122
124
|
- !ruby/object:Gem::Version
|
123
125
|
version: '0'
|
124
126
|
requirements: []
|
125
|
-
rubygems_version: 3.
|
127
|
+
rubygems_version: 3.1.2
|
126
128
|
signing_key:
|
127
129
|
specification_version: 4
|
128
130
|
summary: Write a short summary, because RubyGems requires one.
|
data/.circleci/config.yml
DELETED
@@ -1,18 +0,0 @@
|
|
1
|
-
version: 2
|
2
|
-
jobs:
|
3
|
-
run_tests:
|
4
|
-
docker:
|
5
|
-
- image: circleci/ruby:2.7
|
6
|
-
|
7
|
-
working_directory: ~/userializer
|
8
|
-
|
9
|
-
steps:
|
10
|
-
- checkout
|
11
|
-
- run: bundle install --path=vendor/bundle
|
12
|
-
- run: bundle exec rspec --color --require spec_helper --format progress spec
|
13
|
-
|
14
|
-
workflows:
|
15
|
-
version: 2
|
16
|
-
test:
|
17
|
-
jobs:
|
18
|
-
- run_tests
|