Module: Toar

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

Overview

Deserialize JSON to ActiveRecord Model with associations

Defined Under Namespace

Modules: Ar

Constant Summary collapse

VERSION =
"0.0.1"

Class Method Summary collapse

Class Method Details

.convert_includes_option(*opt) ⇒ Object



51
52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/toar.rb', line 51

def self.convert_includes_option(*opt)
  r = []
  opt.flatten.each do |i|
    case i
    when Symbol
      r << i
    when Hash
      i.each do |k, v|
        r << { k => convert_includes_option(v) }
      end
    end
  end
  { include: r }
end

.to_ar(klass, val, base_object = nil) ⇒ Object



7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
# File 'lib/toar.rb', line 7

def self.to_ar(klass, val, base_object = nil)
  d = val.class == Hash ? val.dup : JSON.parse(val)
  obj = base_object || klass.new

  hmt = klass.reflect_on_all_associations(:has_many).reduce({}) do |r, i|
    r[i.options[:through]] = i if i.options[:through]
    r
  end

  d.except(*obj.attributes.keys).each do |k, v|
    as = klass.reflect_on_association(k)
    next unless as

    case as.macro
    when :belongs_to
      d.delete("#{k}_id")
      to_ar(as.klass, v, obj.send("build_#{k}"))
      obj.class_eval do
        define_method("#{k}_id") { obj.send(k).id }
      end
    when :has_one
      to_ar(as.klass, v, obj.send("build_#{k}"))
    when :has_many
      obj.send(k).proxy_association.target =
        v.map { |i| to_ar(as.klass, i) }

      as_th = hmt[k.to_sym]
      if as_th
        obj.send(as_th.name).proxy_association.target =
          v.map { |i| to_ar(as_th.klass, i[as_th.source_reflection_name.to_s]) }
      end
    end
  end
  obj.assign_attributes(d.slice(*obj.attributes.keys))

  obj.instance_eval do
    # prevent save
    def valid?(_context = nil)
      false
    end
  end
  obj
end