Module: Jsonize

Defined in:
lib/jsonize.rb,
lib/jsonize/version.rb

Defined Under Namespace

Modules: Collection, Relation

Constant Summary collapse

DEFAULT_EXCEPT_ATTRS =
[:created_at, :updated_at]
JSONIZE_ATTRS =
{
   created_at: nil,
   updated_at: nil,
}
ORMS =
{
   ActiveRecord: 'active_record'
}
JSON_TYPES =
[String, Integer, TrueClass, FalseClass, NilClass, Hash, Array]
VERSION =
"0.3.0"

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.detect_ormObject



245
246
247
248
249
250
# File 'lib/jsonize.rb', line 245

def detect_orm
   Object.constants.each do |anc|
      orm = ORMS.keys.find {|re| /#{re}/ =~ anc.to_s }
      require("jsonize/orm/#{ORMS[orm]}") if orm
   end
end

.included(kls) ⇒ Object



241
242
243
# File 'lib/jsonize.rb', line 241

def included kls
   kls.include(Redisize)
end

Instance Method Details

#additional_attrsObject

TODO where is the addtional sources for attributes



24
25
26
27
28
29
30
31
32
33
34
# File 'lib/jsonize.rb', line 24

def additional_attrs
   attributes = self.instance_variable_get(:@attributes).send(:attributes)

   if attributes.is_a?(ActiveModel::LazyAttributeHash)
      attributes.send(:additional_types)
   elsif attributes.is_a?(Hash)
      attributes
   else
      raise
   end
end

#as_json(options = {}) ⇒ Object



170
171
172
173
174
# File 'lib/jsonize.rb', line 170

def as_json options = {}
   attr_props = jsonize_scheme_for(self.class, attibute_tree(self.class, options))

   generate_json(self, attr_props, options)
end

#attibute_tree(klass, options = {}) ⇒ Object



125
126
127
128
129
# File 'lib/jsonize.rb', line 125

def attibute_tree klass, options = {}
   options[:only] ||
   jsonize_attributes_except(self.class == klass ? self.attribute_names : klass.attribute_names,
      options[:except] || default_except_attributes)
end

#collect_attributes(h, model, name, key, value) ⇒ Object



107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
# File 'lib/jsonize.rb', line 107

def collect_attributes h, model, name, key, value
   base = [ ->(this) { this.respond_to?(:read_attribute) ? this.read_attribute("_#{name}") : nil } ]

   props =
   unless value
      [model._reflections[name.to_s],
      model.instance_methods.include?(name.to_sym) ? model.instance_method(name.to_sym) : nil,
      ->(this) { this.is_a?(Hash) ? this[name] : nil },
      (self.class == model ? self.attribute_names : model.attribute_names).include?(name.to_s) ?
      ->(this) { this.respond_to?(:read_attribute) ? this.read_attribute(name) : nil } : nil,
      ].compact
   else
      [value]
   end

   h.merge(key => base.concat(props))
end

#default_except_attributesObject



19
20
21
# File 'lib/jsonize.rb', line 19

def default_except_attributes
   DEFAULT_EXCEPT_ATTRS
end

#dejsonize(options = {}) ⇒ Object



165
166
167
168
# File 'lib/jsonize.rb', line 165

def dejsonize options = {}
   attr_tree = attibute_tree(self.class, options)
   deredisize_json(attr_tree)
end

#generate_json(flow, attr_props, options = {}) ⇒ Object



52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
# File 'lib/jsonize.rb', line 52

def generate_json flow, attr_props, options = {}
  in_h = (options[:externals] || {}).map {|(x, y)| [x.to_s, y] }.to_h

  attr_props.reduce(in_h) do |cr, (name, props)|
      value =
         [props].flatten.reduce(nil) do |r, source|
            case source
            when UnboundMethod
               r ||
                  begin
                     source.bind(flow)[]
                  rescue ActiveModel::MissingAttributeError, TypeError, NoMethodError
                  rescue Exception => e
                     $stderr.puts("#{e.class}: #{e.message}")
                     # binding.pry
                  end
            when Proc
               r || source[flow]
            when Hash, ActiveRecord::Reflection::AbstractReflection
               o = !options[:only] ? options :
                  options[:only].is_a?(Hash) ? options.merge(only: options[:only][name]) :
                  options.merge(only: nil)

               generate_relation(r || flow.respond_to?(name) && flow.send(name) || nil, source, o)
            when NilClass
               r
            else
               raise
            end
         end

      cr.merge(name.to_s => proceed_value(value))
   end
end

#generate_relation(rela, source_in, options) ⇒ Object



36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
# File 'lib/jsonize.rb', line 36

def generate_relation rela, source_in, options
   attr_props = source_in.is_a?(Hash) ? source_in : source_in.polymorphic? ?
      {} : jsonize_scheme_for(source_in.klass, attibute_tree(source_in.klass, options))

   case rela
   when Enumerable
      rela.map do |rec|
         generate_json(rec, attr_props, options)
      end
   when NilClass
      nil
   when Object
      generate_json(rela, attr_props, options)
   end
end

#jsonize(options = {}) ⇒ Object



156
157
158
159
160
161
162
163
# File 'lib/jsonize.rb', line 156

def jsonize options = {}
   attr_tree = attibute_tree(self.class, options)

   redisize_json(attr_tree) do
      attr_props = jsonize_scheme_for(self.class, attr_tree)
      generate_json(self, attr_props, options)
   end
end

#jsonize_attributes_except(a_in, except_in) ⇒ Object



135
136
137
138
139
140
141
142
143
# File 'lib/jsonize.rb', line 135

def jsonize_attributes_except a_in, except_in
   except_in.reduce(a_in) do |res, name|
      if res.include?(name)
         res.delete(name)
      end

      res
   end
end

#jsonize_scheme_for(klass, attr_tree) ⇒ Object



131
132
133
# File 'lib/jsonize.rb', line 131

def jsonize_scheme_for klass, attr_tree
   jsonize_schemes[attr_tree] ||= prepare_attributes(klass, attr_tree)
end

#jsonize_schemesObject



145
146
147
148
149
150
# File 'lib/jsonize.rb', line 145

def jsonize_schemes
   schemes = self.class.instance_variable_get(:@jsonize_schemes) || {}
   self.class.instance_variable_set(:@jsonize_schemes, schemes)

   schemes
end

#prepare_attributes(model, attrs) ⇒ Object



91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
# File 'lib/jsonize.rb', line 91

def prepare_attributes model, attrs
   attrs.reduce({}) do |h, x|
      if x.is_a?(Hash)
         x.reduce(h) do |hh, (sub, subattrs)|
            if submodel = model._reflections[sub]&.klass
               collect_attributes(hh, model, sub, sub.to_sym, prepare_attributes(submodel, subattrs))
            else
               hh
            end
         end
      else
         collect_attributes(h, model, x, x.to_s.sub(/^_/, '').to_sym, nil)
      end
   end
end

#primary_keyObject



152
153
154
# File 'lib/jsonize.rb', line 152

def primary_key
   @primary_key
end

#proceed_value(value_in) ⇒ Object



87
88
89
# File 'lib/jsonize.rb', line 87

def proceed_value value_in
   (value_in.class.ancestors & JSON_TYPES).any? ? value_in : value_in.to_s
end