gql_serializer 2.1.1 → 2.2.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a4b24905733b11703d61b47189d122288eadee6c4511838b4bc3efba2d33b504
4
- data.tar.gz: 8608172dd3bad29a46640022addd1015c7dab4662b1a0e86fc0c5719e1b8032f
3
+ metadata.gz: 1d8e3d8ba95425285d54b5e60ef3d871964b9753888a0142234ab5e2b3946062
4
+ data.tar.gz: 7870f9feb370d956d6e556f10e5542c108341d83a20f81e2faa77beceee4a21a
5
5
  SHA512:
6
- metadata.gz: c169b3e41630853917d0b551592574b9b4002ac42f95554a8a1e6a944b2fc564ed85fa716021b6e90ff5e441ccdf313e1a866ec3cfc1795779cc5968367b2d9c
7
- data.tar.gz: deb01d41687b3036b0c2f89eeae90cf0d0f7ef18c20f1d9efc9917e0f05b03a0caf24d6c881462fddd8e669f87d602b3f9822812bb415c53b76bcac53f083231
6
+ metadata.gz: 1c741e6372a5c1a4e970de523867b798a775559e21815ca4e8995bbb8c1b5832f1ab725e29b2fa02fe6cd4fae28f166cf91308ef42993cb29008558afa1f7e81
7
+ data.tar.gz: 8cb2f9357675f3abeaa3a3bd1d21aae86c7adca3f3c44942bf4b0446785e26a4a4ad84435066fd241452733da5340739d8620d12753c47eed06f51e6d2422010
data/Gemfile.lock CHANGED
@@ -1,30 +1,30 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- gql_serializer (2.1.1)
5
- activerecord (>= 5.2, < 6.1)
4
+ gql_serializer (2.2.0)
5
+ activerecord (>= 5.2, < 8.0)
6
6
 
7
7
  GEM
8
8
  remote: https://rubygems.org/
9
9
  specs:
10
- activemodel (6.0.3.5)
11
- activesupport (= 6.0.3.5)
12
- activerecord (6.0.3.5)
13
- activemodel (= 6.0.3.5)
14
- activesupport (= 6.0.3.5)
15
- activesupport (6.0.3.5)
10
+ activemodel (6.1.5)
11
+ activesupport (= 6.1.5)
12
+ activerecord (6.1.5)
13
+ activemodel (= 6.1.5)
14
+ activesupport (= 6.1.5)
15
+ activesupport (6.1.5)
16
16
  concurrent-ruby (~> 1.0, >= 1.0.2)
17
- i18n (>= 0.7, < 2)
18
- minitest (~> 5.1)
19
- tzinfo (~> 1.1)
20
- zeitwerk (~> 2.2, >= 2.2.2)
17
+ i18n (>= 1.6, < 2)
18
+ minitest (>= 5.1)
19
+ tzinfo (~> 2.0)
20
+ zeitwerk (~> 2.3)
21
21
  coderay (1.1.3)
22
- concurrent-ruby (1.1.8)
22
+ concurrent-ruby (1.1.9)
23
23
  diff-lcs (1.4.4)
24
- i18n (1.8.9)
24
+ i18n (1.10.0)
25
25
  concurrent-ruby (~> 1.0)
26
26
  method_source (1.0.0)
27
- minitest (5.14.4)
27
+ minitest (5.15.0)
28
28
  pry (0.13.1)
29
29
  coderay (~> 1.1)
30
30
  method_source (~> 1.0)
@@ -43,10 +43,9 @@ GEM
43
43
  rspec-support (~> 3.10.0)
44
44
  rspec-support (3.10.0)
45
45
  sqlite3 (1.4.2)
46
- thread_safe (0.3.6)
47
- tzinfo (1.2.9)
48
- thread_safe (~> 0.1)
49
- zeitwerk (2.4.2)
46
+ tzinfo (2.0.4)
47
+ concurrent-ruby (~> 1.0)
48
+ zeitwerk (2.5.4)
50
49
 
51
50
  PLATFORMS
52
51
  ruby
data/README.md CHANGED
@@ -120,7 +120,11 @@ In a Rails application, the configuration can be added to an initializer in `con
120
120
 
121
121
  ```ruby
122
122
  GqlSerializer.configure do |config|
123
- config.case = GqlSerializer::Configuration::NONE_CASE # no case conversion
123
+ # no case conversion
124
+ config.case = GqlSerializer::Configuration::NONE_CASE
125
+ # set to true to avoid additional query in some cases.
126
+ # The default of false avoids a potential breaking change from version 2.1 to 2.2
127
+ config.preload = false
124
128
  end
125
129
  ```
126
130
 
@@ -32,5 +32,5 @@ Gem::Specification.new do |spec|
32
32
  spec.add_development_dependency "pry", "~> 0.13.1"
33
33
  spec.add_development_dependency "sqlite3", "~> 1.4.2"
34
34
 
35
- spec.add_runtime_dependency "activerecord", ">= 5.2", "< 7.0"
35
+ spec.add_runtime_dependency "activerecord", ">= 5.2", "< 8.0"
36
36
  end
@@ -11,7 +11,7 @@ module GqlSerializer
11
11
  reset
12
12
  end
13
13
 
14
- attr_reader :case
14
+ attr_reader :case, :preload
15
15
 
16
16
  def case=(value)
17
17
  raise "Specified case '#{value}' is not supported" unless SUPPORTED_CASES.include?(value)
@@ -20,6 +20,7 @@ module GqlSerializer
20
20
 
21
21
  def reset
22
22
  @case = NONE_CASE
23
+ @preload = false # Default will be true in version 3+
23
24
  end
24
25
 
25
26
  def to_h
@@ -9,10 +9,10 @@ module GqlSerializer
9
9
 
10
10
  module Relation
11
11
  def as_gql(query = nil, options = {})
12
+ options_with_defaults = GqlSerializer.configuration.to_h.merge(options)
12
13
  query_hasharray = query ? GqlSerializer.parse_query(query) : []
13
14
  include_hasharray = GqlSerializer.query_include(self.model, query_hasharray)
14
15
  records = self.includes(include_hasharray).records
15
- options_with_defaults = GqlSerializer.configuration.to_h.merge(options)
16
16
  GqlSerializer.serialize(records, query_hasharray, options_with_defaults)
17
17
  end
18
18
  end
@@ -23,12 +23,26 @@ module GqlSerializer
23
23
  end
24
24
 
25
25
  def as_gql(query = nil, options = {})
26
-
26
+ options_with_defaults = GqlSerializer.configuration.to_h.merge(options)
27
27
  query_hasharray = query ? GqlSerializer.parse_query(query) : []
28
28
  include_hasharray = GqlSerializer.query_include(self.class, query_hasharray)
29
- record = include_hasharray.empty? ? self : self.class.where(id: self).includes(include_hasharray).first
30
- options_with_defaults = GqlSerializer.configuration.to_h.merge(options)
31
- GqlSerializer.serialize(record, query_hasharray, options_with_defaults)
29
+ if options_with_defaults[:preload]
30
+ GqlSerializer._preload([self], include_hasharray)
31
+ GqlSerializer.serialize(self, query_hasharray, options_with_defaults)
32
+ else
33
+ record = include_hasharray.empty? ? self : self.class.where(id: self).includes(include_hasharray).first
34
+ GqlSerializer.serialize(record, query_hasharray, options_with_defaults)
35
+ end
36
+ end
37
+ end
38
+
39
+ def self._preload(records, include_hasharray)
40
+ if ::ActiveRecord::VERSION::MAJOR >= 7
41
+ ::ActiveRecord::Associations::Preloader.
42
+ new(records: records, associations: include_hasharray).call
43
+ else
44
+ ::ActiveRecord::Associations::Preloader.
45
+ new.preload(records, include_hasharray)
32
46
  end
33
47
  end
34
48
  end
@@ -1,3 +1,3 @@
1
1
  module GqlSerializer
2
- VERSION = "2.1.1"
2
+ VERSION = "2.2.0"
3
3
  end
@@ -27,15 +27,15 @@ module GqlSerializer
27
27
 
28
28
  def self.query_include(model, hasharray)
29
29
  include_array = []
30
- relations = model.reflections.keys
31
- hasharray.each do |e|
32
- if e.is_a? String
33
- key = e.split(':')[0]
34
- include_array.push(key) if relations.include?(key)
35
- elsif e.is_a? Hash
36
- key = e.keys.first.split(':')[0]
30
+ relations = model.reflections
31
+ hasharray.each do |element|
32
+ if element.is_a? String
33
+ key = element.split(':')[0]
34
+ include_array.push(key) if relations[key]
35
+ elsif element.is_a? Hash
36
+ key = element.keys.first.split(':')[0]
37
37
  relation_model = model.reflections[key].klass
38
- relation_hasharray = self.query_include(relation_model, e.values.first)
38
+ relation_hasharray = self.query_include(relation_model, element.values.first)
39
39
  if relation_hasharray.empty?
40
40
  include_array.push(key)
41
41
  else
@@ -46,53 +46,71 @@ module GqlSerializer
46
46
  include_array
47
47
  end
48
48
 
49
- def self.serialize(record, hasharray, options)
49
+ # example hasharray = ["id", "name", "tags", { "panels" => ["id", { "cards" => ["content"] }] }]
50
+ def self.serialize(records, hasharray, options, instructions = {})
50
51
 
51
- if record.nil?
52
+ if records.nil?
52
53
  return nil
53
54
  end
54
55
 
55
- if record.respond_to? :map
56
- return record.map do |r|
57
- self.serialize(r, hasharray, options)
56
+
57
+ if records.respond_to? :map
58
+ return records.map do |record|
59
+ self.serialize(record, hasharray, options, instructions)
58
60
  end
59
61
  end
62
+ record = records
60
63
 
61
- hash = {}
62
- model = record.class
63
- all_relations = model.reflections.keys
64
+ id = "#{record.class}, #{hasharray}"
65
+ instruction = instructions[id]
66
+ if (!instruction)
67
+ instruction = {klass: record.class, hasharray: hasharray, relations: [], attributes: []}
68
+ instructions[id] = instruction
64
69
 
65
- relations = hasharray.filter do |e|
66
- next true if !e.is_a?(String)
67
70
 
68
- key, alias_key = e.split(':')
69
- all_relations.include?(key)
70
- end
71
+ model = record.class
72
+ all_relations = model.reflections.keys
71
73
 
72
- attributes = hasharray - relations
73
- attributes = model.attribute_names if attributes.empty?
74
+ relations = hasharray.filter do |relation|
75
+ next true if !relation.is_a?(String)
74
76
 
75
- attributes.each do |e|
76
- key, alias_key = e.split(':')
77
- alias_key = apply_case(alias_key || key, options[:case])
77
+ key, alias_key = relation.split(':')
78
78
 
79
- hash[alias_key] = coerce_value(record.public_send(key))
80
- end
79
+ all_relations.include?(key)
80
+ end
81
81
 
82
- relations.each do |e|
83
- if e.is_a? String
84
- key, alias_key = e.split(':')
85
- alias_key = apply_case(alias_key || key, options[:case])
82
+ attributes = hasharray - relations
83
+ attributes = model.attribute_names if attributes.empty?
86
84
 
87
- rel_records = record.public_send(key)
88
- hash[alias_key] = self.serialize(rel_records, [], options)
89
- else
90
- key, alias_key = e.keys.first.split(':')
85
+ attributes.each do |attribute|
86
+ key, alias_key = attribute.split(':')
91
87
  alias_key = apply_case(alias_key || key, options[:case])
92
88
 
93
- rel_records = record.public_send(key)
94
- hash[alias_key] = self.serialize(rel_records, e.values.first, options)
89
+ instruction[:attributes].push({key: key, alias_key: alias_key})
95
90
  end
91
+
92
+ relations.each do |relation|
93
+ if relation.is_a? String
94
+ key, alias_key = relation.split(':')
95
+ alias_key = apply_case(alias_key || key, options[:case])
96
+
97
+ instruction[:relations].push({key: key, alias_key: alias_key, hasharray: []})
98
+ else
99
+ key, alias_key = relation.keys.first.split(':')
100
+ alias_key = apply_case(alias_key || key, options[:case])
101
+
102
+ instruction[:relations].push({key: key, alias_key: alias_key, hasharray: relation.values.first})
103
+ end
104
+ end
105
+ end
106
+
107
+ hash = {}
108
+ instruction[:attributes].each do |attribute|
109
+ hash[attribute[:alias_key]] = coerce_value(record.public_send(attribute[:key]))
110
+ end
111
+ instruction[:relations].each do |relation|
112
+ relation_records = record.public_send(relation[:key])
113
+ hash[relation[:alias_key]] = self.serialize(relation_records, relation[:hasharray], options, instructions)
96
114
  end
97
115
 
98
116
  hash
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gql_serializer
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.1.1
4
+ version: 2.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew Scullion
@@ -75,7 +75,7 @@ dependencies:
75
75
  version: '5.2'
76
76
  - - "<"
77
77
  - !ruby/object:Gem::Version
78
- version: '7.0'
78
+ version: '8.0'
79
79
  type: :runtime
80
80
  prerelease: false
81
81
  version_requirements: !ruby/object:Gem::Requirement
@@ -85,7 +85,7 @@ dependencies:
85
85
  version: '5.2'
86
86
  - - "<"
87
87
  - !ruby/object:Gem::Version
88
- version: '7.0'
88
+ version: '8.0'
89
89
  description: A gem that adds `as_gql` to easily serialize ActiveRecord objects
90
90
  email:
91
91
  - andrewsc32@protonmail.com