class SK::SDK::Sync
Provide methods for mapping and syncing the fields of a remote to local object. Sync
needs a local(left), a remote(right) object and a field-map(Array) to map the field-names between those two. Optionally you can add transition methods to convert the values from on side to the other.
When syncing the corresponding fields, the names are simply send to each object.
After an object was updated you can check the log
for changes. Sync
does not save anything, it only sets the field values on the other object.
Example¶ ↑
map =[ [:name, :full_name, :'someClass.set_local_name', :'MyClass.set_remote_name'], [:street, :address1] ] map = SK::SDK::Sync.new(@local_user, @remote_user, map) map.update(:r)
Mapping Explained¶ ↑
Mappings are passed as an array:
[ [:local_field_name, :remote_field_name, "MyClass.local_trans", "MyClass.remote_trans"] [:firstname, :first_name, :'MyClass.set_local_name', :'MyClass.set_remote_name'] ]
A mapping consist of a local and the remote field(method) name. And might contain transition methods, if the value needs to be changed when set from one side to the other. Those methods will be called with the value from the other side.
local_obj.field = MyClass.local_trans(remote_obj.field)
Attributes
@return [Array<Field>] mapped fields
@return [Object] The local object
@return [Array<String>] log of field changes
@return [Array<Field>] outdated fields
@return [Object] The remote object
Public Class Methods
@param [Object] local_object @param [Object] remote_object @param [Array<String,Symbol>] field_map assign local to remote field names
# File lib/sk_sdk/sync.rb, line 54 def initialize(local_object, remote_object, field_map) @l_obj = local_object @r_obj = remote_object self.fields = field_map @log = [] end
Public Instance Methods
Find a field by its local name
@param [Symbol] l_name local name @return [Field]
# File lib/sk_sdk/sync.rb, line 73 def field(l_name) fields.find{|fld| fld.l_name == l_name} end
Create field for given mapping arrays and resets all existing ones @param [Array<Array>] field_maps
# File lib/sk_sdk/sync.rb, line 63 def fields=(field_maps) @fields = [] field_maps.each { |fld| @fields << Field.new(fld) } @fields end
Check if the any of the fields are outdated Populates outdated
with local field names
@return [Boolean] false if not outdated
# File lib/sk_sdk/sync.rb, line 81 def outdated? @outdated = [] fields.each do |fld| if fld.transition? # call r_trans method with local val to compare local with remote val # SomeTrans.remote_transfer_method( l_obj.field ) virtual_l_val = eval "#{fld.r_trans} l_obj.send( fld.l_name )" @outdated << fld if virtual_l_val != r_obj.send( fld.r_name ) else # no transfer method, directly compare values @outdated << fld if r_obj.send( fld.r_name ) != l_obj.send( fld.l_name ) end end !@outdated.empty? end
Update a side with the values from the other side. Populates the log with updated fields and values.
@param [String|Symbol] side to update l OR r @param [Array<Field>, nil] flds fields to update, default nil update all fields
# File lib/sk_sdk/sync.rb, line 111 def update(side, flds=nil) raise ArgumentError, 'The side to update must be :l or :r' unless [:l, :r].include?(side) target, source = (side==:l) ? [:l, :r] : [:r, :l] # use set field/s or update all flds ||= fields target_obj = self.send("#{target}_obj") source_obj = self.send("#{source}_obj") flds.each do |fld| target_name = fld.send("#{target}_name") source_name = fld.send("#{source}_name") # remember for log old_val = target_obj.send(target_name) rescue 'empty' # get new value through transfer method or direct new_val = if fld.transition? cur_trans = fld.send("#{target}_trans") eval "#{cur_trans} source_obj.send( source_name )" else source_obj.send( source_name ) end target_obj.send( "#{target_name}=" , new_val ) log << "#{target_name} was: #{old_val} updated from: #{source_name} with value: #{new_val}" end end
update all local outdated fields with values from remote object
# File lib/sk_sdk/sync.rb, line 98 def update_local_outdated update(:l, @outdated) if outdated? end
update all remote outdated fields with values from local object
# File lib/sk_sdk/sync.rb, line 102 def update_remote_outdated update( :r, @outdated) if outdated? end