Module: Replicate::AR::InstanceMethods

Defined in:
lib/replicate/active_record.rb

Overview

Mixin for the ActiveRecord instance.

Instance Method Summary collapse

Instance Method Details

#dump_all_association_replicants(dumper, association_type) ⇒ Object

Dump all associations of a given type.

dumper - The Dumper object used to dump additional objects. association_type - :has_one, :belongs_to, :has_many

Returns nothing.



86
87
88
89
90
91
92
93
94
95
96
97
98
# File 'lib/replicate/active_record.rb', line 86

def dump_all_association_replicants(dumper, association_type)
  self.class.reflect_on_all_associations(association_type).each do |reflection|
    next if self.class.replicate_omit_attributes.include?(reflection.name)
    next if (dependent = __send__(reflection.name)).nil?
    case dependent
    when ActiveRecord::Base, Array
      dumper.dump(dependent)
    else
      warn "warn: #{self.class}##{reflection.name} #{association_type} association " \
           "unexpectedly returned a #{dependent.class}. skipping."
    end
  end
end

#dump_association_replicants(dumper, association) ⇒ Object

Dump objects associated with an AR object through an association name.

object - AR object instance. association - Name of the association whose objects should be dumped.

Returns nothing.



106
107
108
109
110
111
112
113
114
115
116
# File 'lib/replicate/active_record.rb', line 106

def dump_association_replicants(dumper, association)
  if reflection = self.class.reflect_on_association(association)
    objects = __send__(reflection.name)
    dumper.dump(objects)
    if reflection.macro == :has_and_belongs_to_many
      dump_has_and_belongs_to_many_replicant(dumper, reflection)
    end
  else
    warn "error: #{self.class}##{association} is invalid"
  end
end

#dump_has_and_belongs_to_many_replicant(dumper, reflection) ⇒ Object

Dump the special Habtm object used to establish many-to-many relationships between objects that have already been dumped. Note that this object and all objects referenced must have already been dumped before calling this method.



122
123
124
# File 'lib/replicate/active_record.rb', line 122

def dump_has_and_belongs_to_many_replicant(dumper, reflection)
  dumper.dump Habtm.new(self, reflection)
end

#dump_replicant(dumper) ⇒ Object

Replicate::Dumper calls this method on objects to trigger dumping a replicant object tuple. The default implementation dumps all belongs_to associations, then self, then all has_one associations, then any has_many or has_and_belongs_to_many associations declared with the replicate_associations macro.

dumper - Dumper object whose #write method must be called with the

type, id, and attributes hash.

Returns nothing.



22
23
24
25
26
27
28
29
# File 'lib/replicate/active_record.rb', line 22

def dump_replicant(dumper)
  dump_all_association_replicants dumper, :belongs_to
  dumper.write self.class.to_s, id, replicant_attributes, self
  dump_all_association_replicants dumper, :has_one
  self.class.replicate_associations.each do |association|
    dump_association_replicants dumper, association
  end
end

#replicant_attributesObject

Attributes hash used to persist this object. This consists of simply typed values (no complex types or objects) with the exception of special foreign key values. When an attribute value is [:id, “SomeClass:1234”], the loader will handle translating the id value to the local system’s version of the same object.



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
# File 'lib/replicate/active_record.rb', line 36

def replicant_attributes
  attributes = self.attributes.dup
  self.class.replicate_omit_attributes.each do |omit|
    attributes.delete(omit.to_s)
  end
  self.class.reflect_on_all_associations(:belongs_to).each do |reflection|
    options = reflection.options
    if options[:polymorphic]
      if ::ActiveRecord::VERSION::MAJOR == 3 && ::ActiveRecord::VERSION::MINOR > 0
        reference_class = attributes[reflection.foreign_type]
      else
        reference_class = attributes[options[:foreign_type]]
      end
      next if reference_class.nil?

      klass = Kernel.const_get(reference_class)
      primary_key = klass.primary_key
      foreign_key = "#{reflection.name}_id"
    else
      klass = reflection.klass
      primary_key = (options[:primary_key] || klass.primary_key).to_s
      foreign_key = (options[:foreign_key] || "#{reflection.name}_id").to_s
    end
    if primary_key == klass.primary_key
      if id = attributes[foreign_key]
        attributes[foreign_key] = [:id, klass.to_s, id]
      else
        # nil value in association reference
      end
    else
      # association uses non-primary-key foreign key. no special key
      # conversion needed.
    end
  end
  attributes
end

#replicant_idObject

The replicant id is a two tuple containing the class and object id. This is used by Replicant::Dumper to determine if the object has already been dumped or not.



76
77
78
# File 'lib/replicate/active_record.rb', line 76

def replicant_id
  [self.class.name, id]
end