jsonize 0.1.0 → 0.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.
Files changed (4) hide show
  1. checksums.yaml +4 -4
  2. data/lib/jsonize/version.rb +1 -1
  3. data/lib/jsonize.rb +100 -58
  4. metadata +3 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 787277d3b1f9c06c0e3df496dcb3402ceaf1643ee5048ac359bc7592a67487b9
4
- data.tar.gz: 1005708186a5a16ee757b5b4d0393a2af6403465c6377f4ef8defbf50d62df79
3
+ metadata.gz: d3227e59ca0f4826ae7a108ba9ab99419e2441fa7ca4182cd288000fe5caaa5b
4
+ data.tar.gz: 5d79a0a28100a90b628b96820d250a10fa9b70806203b078d68c7828a035d88a
5
5
  SHA512:
6
- metadata.gz: e469b13fd8e298a003d31438dfe78dba30cf0154732e44d3c31246c75417629383a4d6499d132a2b92c003682ccba9893ded343f2d8f241e81b8f6e678402c2c
7
- data.tar.gz: 8ac936e618c70b4eb5b14f6fec34754d2e4806225e23d0b9177f505b82efa91bbb6b66b87a38ca333b12f7026af0c36dce60700a3d892bb8956d3e77d7258afe
6
+ metadata.gz: e427382e3c42a97b5991c2d382a078a198562c1686c835e7039546de9ce360890c8cd6ada52bb3339c1835fd9422d686875631ecdad6bf30f312a5bac38480ab
7
+ data.tar.gz: e35614f1087c93893ee1dc739b4c2a85756f632afcb99a419b70afb605714b459f5b8bf3bc2b1e0435527d4ce24999993df61e6c39366eb5c53d01cbda81a7c8
@@ -1,3 +1,3 @@
1
1
  module Jsonize
2
- VERSION = "0.1.0"
2
+ VERSION = "0.2.0"
3
3
  end
data/lib/jsonize.rb CHANGED
@@ -3,7 +3,9 @@ require 'redisize'
3
3
  require "jsonize/version"
4
4
 
5
5
  module Jsonize
6
- JSON_ATTRS = {
6
+ DEFAULT_EXCEPT_ATTRS = [:created_at, :updated_at]
7
+
8
+ JSONIZE_ATTRS = {
7
9
  created_at: nil,
8
10
  updated_at: nil,
9
11
  }
@@ -12,26 +14,13 @@ module Jsonize
12
14
  ActiveRecord: 'active_record'
13
15
  }
14
16
 
15
- def external_attrs options = {}
16
- if externals = options[:externals]
17
- externals.keys.map {|k| [k.to_sym, k.to_sym] }.to_h
18
- else
19
- {}
20
- end
21
- end
22
-
23
- def instance_attrs
24
- self.attribute_names.map {|a| [a.to_sym, true] }.to_h
25
- end
17
+ JSON_TYPES = [String, Integer, TrueClass, FalseClass, NilClass, Hash, Array]
26
18
 
27
- def embed_attrs
28
- begin
29
- self.class.const_get("JSON_ATTRS")
30
- rescue
31
- {}
32
- end
19
+ def default_except_attributes
20
+ DEFAULT_EXCEPT_ATTRS
33
21
  end
34
22
 
23
+ # TODO where is the addtional sources for attributes
35
24
  def additional_attrs
36
25
  attributes = self.instance_variable_get(:@attributes).send(:attributes)
37
26
 
@@ -44,67 +33,120 @@ module Jsonize
44
33
  end
45
34
  end
46
35
 
47
- def generate_json propses, externals = {}
48
- propses.reduce({}) do |r, (name, props)|
36
+ def generate_relation rela, source_in, options
37
+ source = source_in.is_a?(Hash) ? source_in : source_in.polymorphic? ?
38
+ {} : required_attibutes(source_in.klass, {})
39
+
40
+ case rela
41
+ when Enumerable
42
+ rela.map do |rec|
43
+ generate_json(rec, source, options)
44
+ end
45
+ when NilClass
46
+ nil
47
+ when Object
48
+ generate_json(rela, source, options)
49
+ end
50
+ end
51
+
52
+ def generate_json flow, attr_props, options = {}
53
+ in_h = (options[:externals] || {}).map {|(x, y)| [x.to_s, y] }.to_h
54
+
55
+ attr_props.reduce(in_h) do |cr, (name, props)|
49
56
  value =
50
- if props["rule"].is_a?(Proc)
51
- props["rule"][self]
52
- elsif props["rule"].is_a?(String)
53
- externals.fetch(props["rule"].to_sym) { |x| externals[props["rule"]] }
54
- elsif props["real_name"] != name.to_s
55
- read_attribute(props["real_name"]).as_json
56
- elsif props["rule"].instance_variable_get(:@value)
57
- props["rule"].instance_variable_get(:@value)
58
- elsif props["rule"]
59
- read_attribute(props["real_name"] || props["rule"])
57
+ [props].flatten.reduce(nil) do |r, source|
58
+ case source
59
+ when UnboundMethod
60
+ r || source.bind(flow)[]
61
+ when Proc
62
+ r || source[flow]
63
+ when Hash, ActiveRecord::Reflection::AbstractReflection
64
+ generate_relation(r || flow.send(name), source, options)
65
+ else
66
+ raise
67
+ end
60
68
  end
61
69
 
62
- r.merge(name => value)
70
+ cr.merge(name.to_s => proceed_value(value))
63
71
  end
64
72
  end
65
73
 
66
- def prepare_json options = {}
67
- attr_hash = [
68
- instance_attrs,
69
- JSON_ATTRS,
70
- embed_attrs,
71
- additional_attrs,
72
- external_attrs(options),
73
- options[:map] || {}
74
- ].reduce { |r, hash| r.merge(hash.map {|k,v| [k.to_sym, v] }.to_h) }
75
- except = options.fetch(:except, [])
76
- only = options.fetch(:only, self.attributes.keys.map(&:to_sym) | (options[:map] || {}).keys | embed_attrs.keys | external_attrs(options).keys)
74
+ def proceed_value value_in
75
+ (value_in.class.ancestors & JSON_TYPES).any? ? value_in : value_in.to_s
76
+ end
77
77
 
78
- attr_hash.map do |(name_in, rule_in)|
79
- name = /^_(?<_name>.*)/ =~ name_in && _name || name_in.to_s
78
+ def prepare_attributes model, attrs
79
+ attrs.reduce({}) do |h, x|
80
+ if x.is_a?(Hash)
81
+ x.reduce(h) do |hh, (sub, subattrs)|
82
+ if submodel = model._reflections[sub]&.klass
83
+ hh.merge(sub.to_sym => prepare_attributes(submodel, subattrs))
84
+ else
85
+ hh
86
+ end
87
+ end
88
+ else
89
+ props = [
90
+ model._reflections[x.to_s],
91
+ model.instance_methods.include?(x.to_sym) ? model.instance_method(x.to_sym) : nil,
92
+ (self.class == model ? self.attribute_names : model.attribute_names).
93
+ include?(x.to_s) ? ->(this) { this.read_attribute(x) } : nil
94
+ ].compact
95
+
96
+ h.merge(x.to_s.sub(/^_/, '').to_sym => props)
97
+ end
98
+ end
99
+ end
100
+
101
+ def attibute_tree klass, options = {}
102
+ options[:only] ||
103
+ jsonize_attributes_except(self.class == klass ? self.attribute_names : klass.attribute_names,
104
+ options[:except] || default_except_attributes)
105
+ end
106
+
107
+ def jsonize_scheme_for klass, attr_tree
108
+ jsonize_schemes[attr_tree] ||= prepare_attributes(klass, attr_tree)
109
+ end
80
110
 
81
- next nil if except.include?(name.to_sym) || (only & [ name.to_sym, name_in.to_sym ].uniq).blank?
111
+ def jsonize_attributes_except a_in, except_in
112
+ except_in.reduce(a_in) do |res, name|
113
+ if res.include?(name)
114
+ res.delete(name)
115
+ end
82
116
 
83
- rule = parse_rule(rule_in)
84
- #binding.pry
85
- [name, { "rule" => rule, "real_name" => name_in.to_s }]
86
- end.compact.to_h
117
+ res
118
+ end
87
119
  end
88
120
 
89
- def parse_rule rule_in
90
- %w(TrueClass FalseClass NilClass Symbol).all? {|k| !rule_in.is_a?(k.constantize) } && true || rule_in.is_a?(Symbol) && rule_in.to_s || rule_in
121
+ def jsonize_schemes
122
+ schemes = self.class.instance_variable_get(:@jsonize_schemes) || {}
123
+ self.class.instance_variable_set(:@jsonize_schemes, schemes)
124
+
125
+ schemes
126
+ end
127
+
128
+ def primary_key
129
+ @primary_key
91
130
  end
92
131
 
93
132
  def jsonize options = {}
94
- attr_props = prepare_json(options)
95
- redisize_json(attr_props) do
96
- generate_json(attr_props, options[:externals])
133
+ attr_tree = attibute_tree(self.class, options)
134
+
135
+ redisize_json(attr_tree) do
136
+ attr_props = jsonize_scheme_for(self.class, attr_tree)
137
+ generate_json(self, attr_props, options)
97
138
  end
98
139
  end
99
140
 
100
141
  def dejsonize options = {}
101
- attr_props = prepare_json(options)
102
- deredisize_json(attr_props)
142
+ attr_tree = attibute_tree(self.class, options)
143
+ deredisize_json(attr_tree)
103
144
  end
104
145
 
105
146
  def as_json options = {}
106
- attr_props = prepare_json(options)
107
- generate_json(attr_props, options[:externals])
147
+ attr_props = jsonize_scheme_for(self.class, attibute_tree(self.class, options))
148
+
149
+ generate_json(self, attr_props, options)
108
150
  end
109
151
 
110
152
  module Relation
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jsonize
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Pavel «Malo» Skrylev
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-07-26 00:00:00.000000000 Z
11
+ date: 2023-12-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: redisize
@@ -95,7 +95,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
95
95
  - !ruby/object:Gem::Version
96
96
  version: '0'
97
97
  requirements: []
98
- rubygems_version: 3.1.6
98
+ rubygems_version: 3.3.7
99
99
  signing_key:
100
100
  specification_version: 4
101
101
  summary: Act as as_json for active record model or as a jsonize