Class: Mongoid::Max::Denormalize::OneToMany

Inherits:
Base
  • Object
show all
Defined in:
lib/mongoid/max/denormalize/one_to_many.rb

Instance Attribute Summary

Attributes inherited from Base

#fields, #inverse_meta, #klass, #meta, #options

Instance Method Summary collapse

Methods inherited from Base

#allowed_options, array_code_for, #fields_methods, #fields_only, #initialize, #inverse_klass, #inverse_relation, #relation, #unallowed_options, #verify

Constructor Details

This class inherits a constructor from Mongoid::Max::Denormalize::Base

Instance Method Details

#attachObject



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
50
51
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
86
87
88
89
90
91
92
93
94
95
# File 'lib/mongoid/max/denormalize/one_to_many.rb', line 8

def attach
  #
  # This side of the relation
  #
  fields.each do |field|
    field_meta = inverse_klass.fields[field.to_s]
    klass.field "#{relation}_#{field}", type: field_meta.try(:type)
  end

  klass.before_save :"denormalize_from_#{relation}"

  klass.class_eval <<-EOM, __FILE__, __LINE__
    def denormalize_from_#{relation}
      return true unless #{meta.key}_changed?

      fields = [#{Base.array_code_for(fields)}]
      if #{meta.key}.nil?
        fields.each do |field|
          self.send(:"#{relation}_\#{field}=", nil)
        end
      else
        fields.each do |field|
          self.send(:"#{relation}_\#{field}=", #{relation}.send(field))
        end
      end

      true
    end
  EOM

  #
  # Other side of the relation
  #
  inverse_klass.around_save :"denormalize_to_#{inverse_relation}"

  inverse_klass.class_eval <<-EOM, __FILE__, __LINE__
    def denormalize_to_#{inverse_relation}(force = false)
      unless changed? || force
        yield if block_given?
        return
      end

      fields = [#{Base.array_code_for(fields)}]
      fields_only = [#{Base.array_code_for(fields_only)}]
      methods = [#{Base.array_code_for(fields_methods)}]
      changed_fields = force ? fields_only.dup : (fields_only & changed.map(&:to_sym))

      yield if block_given?

      return if changed_fields.count == 0

      to_set = {}
      (changed_fields + methods).each do |field|
        to_set[:"#{relation}_\#{field}"] = send(field)
      end

      #{inverse_relation}.update_all(to_set) unless to_set.empty?
    end
  EOM

  inverse_klass.class_eval <<-EOM, __FILE__, __LINE__
    def self.denormalize_to_#{inverse_relation}!
      all.entries.each do |obj|
        obj.denormalize_to_#{inverse_relation}(true)
      end

      nil
    end
  EOM


  inverse_klass.around_destroy :"denormalize_to_#{inverse_relation}_destroy"

  inverse_klass.class_eval <<-EOM, __FILE__, __LINE__
    def denormalize_to_#{inverse_relation}_destroy
      fields = [#{Base.array_code_for(fields)}]

      yield if block_given?

      to_set = {}
      fields.each do |field|
        to_set[:"#{relation}_\#{field}"] = nil
      end

      #{inverse_relation}.update_all(to_set) unless to_set.empty?
    end
  EOM
end