userializer 0.1.5 → 0.3.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 97fa2e63cfd59d981e9a7f8eac172e31830d53ad572aaab8683e62fa26410d27
4
- data.tar.gz: 1a6c4b3947dcbe65c7b915ef3f5538e68f0b35805860cd5eb2fe03d01e9b7299
3
+ metadata.gz: c60edc59f0b2c8635bec13e771422371ec92bf1eb696957321cea2cd56d14161
4
+ data.tar.gz: 1d7b6365abd81700080e4d63c0995dcca6ff3a24047e22596ea954dd73c4db50
5
5
  SHA512:
6
- metadata.gz: 1f58f0270860f307e07c2d80a8ee620e338e75db06316e1fedd0f7f916c1cafa96122363b5ff7c775cdc2376483718ca07aa84264a284546d4f9bc72c1e373ab
7
- data.tar.gz: '0539527fde035a912a6c97dc1e25d83a49e2a1ada7a30ee9df93f890e7e9d5b76e7b120f88704a2b37f2b9dbaa9c170c4229aeb33f602bb4d4a104c9b4419e7c'
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
@@ -9,3 +9,4 @@
9
9
 
10
10
  # rspec failure tracking
11
11
  .rspec_status
12
+ Gemfile.lock
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
- @serializer = opts[:each_serializer] || USerializer.infered_serializer_class(
23
- obj_class
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
- @serializer.new(obj, @opts).merge_root(res, @root_key, false, opts)
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
@@ -6,7 +6,7 @@ module USerializer
6
6
  @key = key
7
7
 
8
8
  @opts = opts
9
- @id_key = "#{ActiveSupport::Inflector.singularize(key)}_ids".to_sym
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[@id_key] = (ser.send(@key) || []).compact.map do |obj|
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.send(@key) || []
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
@@ -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
- @serializer = opts[:serializer]
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)
@@ -1,3 +1,3 @@
1
1
  module USerializer
2
- VERSION = "0.1.5"
2
+ VERSION = "0.3.1"
3
3
  end
data/lib/userializer.rb CHANGED
@@ -1,6 +1,7 @@
1
1
  require 'userializer/version'
2
2
  require 'userializer/base_serializer'
3
3
  require 'userializer/array_serializer'
4
+ require 'userializer/composite_serializer'
4
5
 
5
6
  module USerializer
6
7
  NS_SEPARATOR = '::'.freeze
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", "~> 1.16"
24
- spec.add_development_dependency "rake", "~> 10.0"
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.5
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: 2019-06-17 00:00:00.000000000 Z
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: '1.16'
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: '1.16'
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: '10.0'
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: '10.0'
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
- rubyforge_project:
126
- rubygems_version: 2.7.3
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