jsonize 0.1.1 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (4) hide show
  1. checksums.yaml +4 -4
  2. data/lib/jsonize/version.rb +1 -1
  3. data/lib/jsonize.rb +104 -72
  4. metadata +3 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: bdb7d503cc06ab7caf4bad0cfb1f7162fab524a76d7cfc5d24c695f58231f5ae
4
- data.tar.gz: 5d4ac6b92ab4f1893d7cd23609460e9f2009bd646f1df4f2878a5fa4db758465
3
+ metadata.gz: d3227e59ca0f4826ae7a108ba9ab99419e2441fa7ca4182cd288000fe5caaa5b
4
+ data.tar.gz: 5d79a0a28100a90b628b96820d250a10fa9b70806203b078d68c7828a035d88a
5
5
  SHA512:
6
- metadata.gz: 93ee3812b793b0dd34f88df23bc3438372d7cfb07d1ddefa72026bd9a064e37e4d5689bb13d46ae8eff5e62e90ee844f16179235d4806ec71519ff6dc87e89f1
7
- data.tar.gz: 8830854c6b28efcdeae92aebef0b75138a6f85fc87be5016931374b7b3c2f32c2cec8a0aa133f6a14db1634d83ed5db7f2ab8be7baa40a1603000611e882809d
6
+ metadata.gz: e427382e3c42a97b5991c2d382a078a198562c1686c835e7039546de9ce360890c8cd6ada52bb3339c1835fd9422d686875631ecdad6bf30f312a5bac38480ab
7
+ data.tar.gz: e35614f1087c93893ee1dc739b4c2a85756f632afcb99a419b70afb605714b459f5b8bf3bc2b1e0435527d4ce24999993df61e6c39366eb5c53d01cbda81a7c8
@@ -1,3 +1,3 @@
1
1
  module Jsonize
2
- VERSION = "0.1.1"
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
17
+ JSON_TYPES = [String, Integer, TrueClass, FalseClass, NilClass, Hash, Array]
22
18
 
23
- def instance_attrs
24
- self.attribute_names.map {|a| [a.to_sym, true] }.to_h
25
- end
26
-
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,77 +33,120 @@ module Jsonize
44
33
  end
45
34
  end
46
35
 
47
- def generate_json propses, options = {}
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"] == '_reflection'
51
- send(name).as_json(options[name.to_sym] || {})
52
- elsif props["rule"].is_a?(String) # NOTE required for sidekiq key
53
- extenrals = options[:externals]
54
- externals.fetch(props["rule"].to_sym) { |x| externals[props["rule"]] }
55
- elsif props["real_name"] != name.to_s
56
- read_attribute(props["real_name"]).as_json
57
- elsif props["rule"].instance_variable_get(:@value)
58
- props["rule"].instance_variable_get(:@value)
59
- elsif props["rule"]
60
- 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
61
68
  end
62
69
 
63
- r.merge(name => value)
70
+ cr.merge(name.to_s => proceed_value(value))
64
71
  end
65
72
  end
66
73
 
67
- def prepare_json options = {}
68
- attr_hash = [
69
- instance_attrs,
70
- JSON_ATTRS,
71
- embed_attrs,
72
- additional_attrs,
73
- external_attrs(options),
74
- options[:map] || {},
75
- _reflections
76
- ].reduce { |r, hash| r.merge(hash.map {|k,v| [k.to_sym, v] }.to_h) }
77
- except = options.fetch(:except, [])
78
- only = options.fetch(:only, self.attributes.keys.map(&:to_sym) | (options[:map] || {}).keys | embed_attrs.keys | external_attrs(options).keys)
79
-
80
- attr_hash.map do |(name_in, rule_in)|
81
- name = /^_(?<_name>.*)/ =~ name_in && _name || name_in.to_s
82
-
83
- next nil if except.include?(name.to_sym) || (only & [ name.to_sym, name_in.to_sym ].uniq).blank?
84
-
85
- rule = parse_rule(rule_in)
86
- [name, { "rule" => rule, "real_name" => name_in.to_s }]
87
- end.compact.to_h
88
- end
89
-
90
- def parse_rule rule_in
91
- case rule_in
92
- when TrueClass, FalseClass, NilClass
93
- true
94
- when ActiveRecord::Reflection::AbstractReflection
95
- '_reflection'
96
- when Symbol, String
97
- rule_in.to_s
98
- else
99
- true
74
+ def proceed_value value_in
75
+ (value_in.class.ancestors & JSON_TYPES).any? ? value_in : value_in.to_s
76
+ end
77
+
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
100
98
  end
101
99
  end
102
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
110
+
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
116
+
117
+ res
118
+ end
119
+ end
120
+
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
130
+ end
131
+
103
132
  def jsonize options = {}
104
- attr_props = prepare_json(options)
105
- redisize_json(attr_props) do
106
- generate_json(attr_props, options)
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)
107
138
  end
108
139
  end
109
140
 
110
141
  def dejsonize options = {}
111
- attr_props = prepare_json(options)
112
- deredisize_json(attr_props)
142
+ attr_tree = attibute_tree(self.class, options)
143
+ deredisize_json(attr_tree)
113
144
  end
114
145
 
115
146
  def as_json options = {}
116
- attr_props = prepare_json(options)
117
- generate_json(attr_props, options)
147
+ attr_props = jsonize_scheme_for(self.class, attibute_tree(self.class, options))
148
+
149
+ generate_json(self, attr_props, options)
118
150
  end
119
151
 
120
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.1
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-08-05 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