Class: SKApi::Utils::FieldMap

Inherits:
Object
  • Object
show all
Defined in:
lib/utils/field_map.rb

Overview

Provide methods for mapping the fields of a remote object to local object The class holds two objects (f.ex. a remote and a local object) and works with a hash which maps the fields between those two. If you use such a mapping both of your objects MUST respond to the method names passed in the mapping-table(hash)

When an object is updated you can check the #log for changes

Example

contact_map = {
   :loc_key => :name,
   :rem_key => :firstname,
   :obj => 'Stanza::SalesKing::Mapping::ContactTrans',
   :loc_trans=>:set_local_name,
   :rem_trans=> :set_remote_name
 }
 map = SKApi::Utils::FieldMap.new(@local_user, @remote_user, contact_map)
 map.update_remote #Does not save! only sets the field values on the remote object

Mapping Hash Explanation

{
  :loc_key => :name,               => Local fieldname    #
  :rem_key => :firstname,          => remote fieldname
  :obj => 'ATransitionClass',      => The class which hold the following Transition methods as Class.methods
  :loc_trans=>:set_local_name,     =>  Method called when local field is updated
  :rem_trans=> :set_remote_name    =>  Method called when remote field is update
}

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(loc_obj, rem_obj, fields) ⇒ FieldMap

Takes a local and remote object which should respond to function defined in the mapping hash



46
47
48
49
50
51
# File 'lib/utils/field_map.rb', line 46

def initialize(loc_obj, rem_obj, fields)
  @loc_obj = loc_obj
  @rem_obj = rem_obj
  @fields = fields
  @log = []
end

Instance Attribute Details

#fieldsObject

<HashSymbol=>{Hash }>::the field mapping



38
39
40
# File 'lib/utils/field_map.rb', line 38

def fields
  @fields
end

#loc_objObject

The local object



34
35
36
# File 'lib/utils/field_map.rb', line 34

def loc_obj
  @loc_obj
end

#logObject (readonly)

<Array>::log field changes



42
43
44
# File 'lib/utils/field_map.rb', line 42

def log
  @log
end

#outdatedObject (readonly)

the outdated fields



40
41
42
# File 'lib/utils/field_map.rb', line 40

def outdated
  @outdated
end

#rem_objObject

The remote object



36
37
38
# File 'lib/utils/field_map.rb', line 36

def rem_obj
  @rem_obj
end

Instance Method Details

#outdated?Boolean

check if the any of the fields are outdated populates self.outdated array with outdated fields

Returns

<Boolean>

false if not outdated

Returns:

  • (Boolean)


57
58
59
60
61
62
63
64
65
66
67
68
69
# File 'lib/utils/field_map.rb', line 57

def outdated?
  @outdated = []
  fields.each do |fld|
    if fld[:trans]
      # SomeTransferObject.remote_tranfer_function(remote_obj_data)
      virtual_local_val  = fld[:trans][:obj].constantize.send( fld[:trans][:rem_trans], loc_obj.send( fld[:loc_key] ) )
      @outdated << fld if virtual_local_val != rem_obj.send( fld[:rem_key] )
    else
      @outdated << fld if rem_obj.send( fld[:rem_key] ) != loc_obj.send( fld[:loc_key] )
    end          
  end
  !@outdated.empty?
end

#update_local(field = nil) ⇒ Object

update all local fields with values from remote



81
82
83
84
85
86
87
88
89
90
91
92
93
94
# File 'lib/utils/field_map.rb', line 81

def update_local(field=nil)
  flds = field ? ( field.is_a?(Array) ? field : [field] ) : fields
  flds.each do |fld|
    old_val = loc_obj.send(fld[:loc_key]) rescue 'empty'
    new_val = if fld[:trans] #call transfer function
                fld[:trans][:obj].constantize.send( fld[:trans][:loc_trans], rem_object.send( fld[:rem_key] ) )
              else # lookup directly on local object
                rem_obj.send(fld[:rem_key])
              end
    loc_obj.send( "#{fld[:loc_key]}=", new_val )
    # write to log
    log << "local: #{fld[:loc_key]} was: #{old_val} updated from remote: #{fld[:rem_key]} with value: #{new_val}"
  end
end

#update_local_outdatedObject

update all local outdated fields wit hvcalues from remote object



72
73
74
# File 'lib/utils/field_map.rb', line 72

def update_local_outdated
  update_local(@outdated) if outdated?
end

#update_remote(field = nil) ⇒ Object

Update all or given remote fields with the value of the local fields



98
99
100
101
102
103
104
105
106
107
108
109
110
# File 'lib/utils/field_map.rb', line 98

def update_remote(field=nil)
  flds = field ? ( field.is_a?(Array) ? field : [field] ) : fields
  flds.each do |fld|
    old_val = rem_obj.send(fld[:rem_key]) rescue 'empty'# rember for log
    new_val = if fld[:trans] #call transfer function
                fld[:trans][:obj].constantize.send( fld[:trans][:rem_trans], loc_obj.send( fld[:loc_key] ) )
              else # lookup directly on local object
                loc_obj.send( fld[:loc_key] )
              end
    rem_obj.send( "#{fld[:rem_key]}=" , new_val )
    log << "remote: #{fld[:rem_key]} was: #{old_val} updated from local: #{fld[:loc_key]} with value: #{new_val}"
  end
end

#update_remote_outdatedObject

update all remote outdated fields wit hvalues from local object



76
77
78
# File 'lib/utils/field_map.rb', line 76

def update_remote_outdated
  update_remote(@outdated) if outdated?
end