userializer 0.1.5 → 0.3.1
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/.circleci/config.yml +18 -0
- data/.gitignore +1 -0
- data/README.md +27 -0
- data/lib/userializer/array_serializer.rb +17 -4
- data/lib/userializer/composite_serializer.rb +78 -0
- data/lib/userializer/has_many.rb +16 -3
- data/lib/userializer/has_one.rb +12 -5
- data/lib/userializer/version.rb +1 -1
- data/lib/userializer.rb +1 -0
- data/userializer.gemspec +2 -2
- metadata +12 -12
- data/Gemfile.lock +0 -50
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c60edc59f0b2c8635bec13e771422371ec92bf1eb696957321cea2cd56d14161
|
4
|
+
data.tar.gz: 1d7b6365abd81700080e4d63c0995dcca6ff3a24047e22596ea954dd73c4db50
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz: '
|
6
|
+
metadata.gz: 7339df9d80d2fcad0b5fe7504b9df90c99d8eb2be1d36886a21c4efbd89b793bb37bd3b464b62aa97af05ae68815e6460e0b7e72fdc99e67d5a8387caf828fd9
|
7
|
+
data.tar.gz: '01383c0f9f6e9b0290d25ac88042bd21465d4d10818c38d1c9c37d4f4ec49e64172506744551c0f4720d65a543467149450b4aad46a0ca7d8f9a6f736bf756d6'
|
@@ -0,0 +1,18 @@
|
|
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
|
data/.gitignore
CHANGED
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.
|
@@ -19,14 +19,18 @@ module USerializer
|
|
19
19
|
ActiveSupport::Inflector.underscore(obj_class.name).split('/').last
|
20
20
|
).to_sym if obj_class
|
21
21
|
|
22
|
-
|
23
|
-
|
24
|
-
)
|
22
|
+
serializer = opts[:each_serializer]
|
23
|
+
|
24
|
+
@serializer = if serializer&.is_a?(Proc)
|
25
|
+
serializer
|
26
|
+
elsif serializer
|
27
|
+
proc { serializer }
|
28
|
+
end
|
25
29
|
end
|
26
30
|
|
27
31
|
def merge_root(res, opts)
|
28
32
|
@objs.each do |obj|
|
29
|
-
|
33
|
+
serializer(obj, opts).merge_root(res, @root_key, false, opts)
|
30
34
|
end
|
31
35
|
end
|
32
36
|
|
@@ -46,5 +50,14 @@ module USerializer
|
|
46
50
|
end
|
47
51
|
|
48
52
|
def scope; @opts[:scope]; end
|
53
|
+
|
54
|
+
private
|
55
|
+
|
56
|
+
def serializer(obj, opts)
|
57
|
+
return @serializer.call(obj, opts).new(obj, @opts) if @serializer
|
58
|
+
return obj.serialize if obj.respond_to?(:serialize)
|
59
|
+
|
60
|
+
USerializer.infered_serializer_class(obj.class).new(obj, @opts)
|
61
|
+
end
|
49
62
|
end
|
50
63
|
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,17 +15,30 @@ 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
|
22
22
|
|
23
23
|
def merge_root(res, ser, opts)
|
24
|
-
objs = ser
|
24
|
+
objs = entities(ser) || []
|
25
25
|
|
26
26
|
return if objs.empty? || !@conditional_block.call(ser.object, opts)
|
27
27
|
|
28
28
|
ArraySerializer.new(objs, @opts).merge_root(res, opts)
|
29
29
|
end
|
30
|
+
|
31
|
+
def entities(ser)
|
32
|
+
obj = ser.send(@key) || []
|
33
|
+
return obj unless @opts[:scope]
|
34
|
+
|
35
|
+
obj.send(@opts[:scope])
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
def build_ids_key(key)
|
41
|
+
"#{ActiveSupport::Inflector.singularize(key)}_ids".to_sym
|
42
|
+
end
|
30
43
|
end
|
31
44
|
end
|
data/lib/userializer/has_one.rb
CHANGED
@@ -3,10 +3,17 @@ module USerializer
|
|
3
3
|
def initialize(key, opts)
|
4
4
|
@key = key
|
5
5
|
@opts = opts
|
6
|
-
@id_key = "#{key}_id".to_sym
|
6
|
+
@id_key = opts[:id_key] || "#{key}_id".to_sym
|
7
7
|
@root_key = opts[:root]&.to_sym
|
8
8
|
|
9
|
-
|
9
|
+
serializer = opts[:serializer]
|
10
|
+
|
11
|
+
@serializer = if serializer&.is_a?(Proc)
|
12
|
+
@serializer = serializer
|
13
|
+
elsif serializer
|
14
|
+
proc { serializer }
|
15
|
+
end
|
16
|
+
|
10
17
|
@embed_key = opts[:embed_key] || :id
|
11
18
|
@conditional_block = opts[:if] || proc { true }
|
12
19
|
end
|
@@ -25,13 +32,13 @@ module USerializer
|
|
25
32
|
|
26
33
|
return if obj.nil? || !@conditional_block.call(ser.object, opts)
|
27
34
|
|
28
|
-
serializer(obj).merge_root(res, root_key(obj), false, opts)
|
35
|
+
serializer(obj, opts).merge_root(res, root_key(obj), false, opts)
|
29
36
|
end
|
30
37
|
|
31
38
|
private
|
32
39
|
|
33
|
-
def serializer(obj)
|
34
|
-
return @serializer.new(obj, @opts) if @serializer
|
40
|
+
def serializer(obj, opts)
|
41
|
+
return @serializer.call(obj, opts).new(obj, @opts) if @serializer
|
35
42
|
return obj.serialize if obj.respond_to?(:serialize)
|
36
43
|
|
37
44
|
USerializer.infered_serializer_class(obj.class).new(obj, @opts)
|
data/lib/userializer/version.rb
CHANGED
data/lib/userializer.rb
CHANGED
data/userializer.gemspec
CHANGED
@@ -20,8 +20,8 @@ Gem::Specification.new do |spec|
|
|
20
20
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
21
21
|
spec.require_paths = ["lib"]
|
22
22
|
|
23
|
-
spec.add_development_dependency "bundler", "~>
|
24
|
-
spec.add_development_dependency "rake", "~>
|
23
|
+
spec.add_development_dependency "bundler", "~> 2.0"
|
24
|
+
spec.add_development_dependency "rake", "~> 13.0"
|
25
25
|
spec.add_development_dependency "rspec", "~> 3.0"
|
26
26
|
spec.add_dependency "oj"
|
27
27
|
spec.add_dependency "activesupport"
|
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.1
|
4
|
+
version: 0.3.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Alexis Montagne
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-10-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -16,28 +16,28 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '
|
19
|
+
version: '2.0'
|
20
20
|
type: :development
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '
|
26
|
+
version: '2.0'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: rake
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: '
|
33
|
+
version: '13.0'
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: '
|
40
|
+
version: '13.0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: rspec
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -87,11 +87,11 @@ executables: []
|
|
87
87
|
extensions: []
|
88
88
|
extra_rdoc_files: []
|
89
89
|
files:
|
90
|
+
- ".circleci/config.yml"
|
90
91
|
- ".gitignore"
|
91
92
|
- ".rspec"
|
92
93
|
- ".travis.yml"
|
93
94
|
- Gemfile
|
94
|
-
- Gemfile.lock
|
95
95
|
- README.md
|
96
96
|
- Rakefile
|
97
97
|
- bin/console
|
@@ -100,6 +100,7 @@ files:
|
|
100
100
|
- lib/userializer/array_serializer.rb
|
101
101
|
- lib/userializer/attribute.rb
|
102
102
|
- lib/userializer/base_serializer.rb
|
103
|
+
- lib/userializer/composite_serializer.rb
|
103
104
|
- lib/userializer/has_many.rb
|
104
105
|
- lib/userializer/has_one.rb
|
105
106
|
- lib/userializer/version.rb
|
@@ -107,7 +108,7 @@ files:
|
|
107
108
|
homepage: https://github.com/upfluence/userializer
|
108
109
|
licenses: []
|
109
110
|
metadata: {}
|
110
|
-
post_install_message:
|
111
|
+
post_install_message:
|
111
112
|
rdoc_options: []
|
112
113
|
require_paths:
|
113
114
|
- lib
|
@@ -122,9 +123,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
122
123
|
- !ruby/object:Gem::Version
|
123
124
|
version: '0'
|
124
125
|
requirements: []
|
125
|
-
|
126
|
-
|
127
|
-
signing_key:
|
126
|
+
rubygems_version: 3.1.4
|
127
|
+
signing_key:
|
128
128
|
specification_version: 4
|
129
129
|
summary: Write a short summary, because RubyGems requires one.
|
130
130
|
test_files: []
|
data/Gemfile.lock
DELETED
@@ -1,50 +0,0 @@
|
|
1
|
-
PATH
|
2
|
-
remote: .
|
3
|
-
specs:
|
4
|
-
userializer (0.1.5)
|
5
|
-
activesupport
|
6
|
-
oj
|
7
|
-
|
8
|
-
GEM
|
9
|
-
remote: https://rubygems.org/
|
10
|
-
specs:
|
11
|
-
activesupport (5.2.3)
|
12
|
-
concurrent-ruby (~> 1.0, >= 1.0.2)
|
13
|
-
i18n (>= 0.7, < 2)
|
14
|
-
minitest (~> 5.1)
|
15
|
-
tzinfo (~> 1.1)
|
16
|
-
concurrent-ruby (1.1.5)
|
17
|
-
diff-lcs (1.3)
|
18
|
-
i18n (1.6.0)
|
19
|
-
concurrent-ruby (~> 1.0)
|
20
|
-
minitest (5.11.3)
|
21
|
-
oj (3.7.12)
|
22
|
-
rake (10.4.2)
|
23
|
-
rspec (3.8.0)
|
24
|
-
rspec-core (~> 3.8.0)
|
25
|
-
rspec-expectations (~> 3.8.0)
|
26
|
-
rspec-mocks (~> 3.8.0)
|
27
|
-
rspec-core (3.8.0)
|
28
|
-
rspec-support (~> 3.8.0)
|
29
|
-
rspec-expectations (3.8.3)
|
30
|
-
diff-lcs (>= 1.2.0, < 2.0)
|
31
|
-
rspec-support (~> 3.8.0)
|
32
|
-
rspec-mocks (3.8.0)
|
33
|
-
diff-lcs (>= 1.2.0, < 2.0)
|
34
|
-
rspec-support (~> 3.8.0)
|
35
|
-
rspec-support (3.8.0)
|
36
|
-
thread_safe (0.3.6)
|
37
|
-
tzinfo (1.2.5)
|
38
|
-
thread_safe (~> 0.1)
|
39
|
-
|
40
|
-
PLATFORMS
|
41
|
-
ruby
|
42
|
-
|
43
|
-
DEPENDENCIES
|
44
|
-
bundler (~> 1.16)
|
45
|
-
rake (~> 10.0)
|
46
|
-
rspec (~> 3.0)
|
47
|
-
userializer!
|
48
|
-
|
49
|
-
BUNDLED WITH
|
50
|
-
1.16.1
|