module RenderSync::ModelChangeTracking

Private Class Methods

included(base) click to toggle source

Set up callback to store record and sync scope states prior the update action

# File lib/render_sync/model_change_tracking.rb, line 6
def self.included(base)
  base.class_eval do
    before_update :store_state_before_update, if: -> { RenderSync::Model.enabled? }
  end
end

Private Instance Methods

entered_new_scope?(definition) click to toggle source

Checks if this record has entered the new (possibly changed) scope defined by the passed scope definition throughout the update process

# File lib/render_sync/model_change_tracking.rb, line 51
def entered_new_scope?(definition)
  scope_after_update(definition).valid? \
    && new_record_in_new_scope?(definition) \
    && !remained_in_old_scope?(definition)
end
left_old_scope?(definition) click to toggle source

Checks if this record has left the old scope defined by the passed scope definition throughout the update process

# File lib/render_sync/model_change_tracking.rb, line 42
def left_old_scope?(definition)
  scope_before_update(definition).valid? \
    && old_record_in_old_scope?(definition) \
    && !new_record_in_old_scope?(definition)
end
new_record_in_new_scope?(definition) click to toggle source
# File lib/render_sync/model_change_tracking.rb, line 88
def new_record_in_new_scope?(definition)
  scope_after_update(definition).contains?(record_after_update)
end
new_record_in_old_scope?(defintion) click to toggle source
# File lib/render_sync/model_change_tracking.rb, line 92
def new_record_in_old_scope?(defintion)
  scope_before_update(defintion).contains?(record_after_update)
end
old_record_in_new_scope?(definition) click to toggle source
# File lib/render_sync/model_change_tracking.rb, line 84
def old_record_in_new_scope?(definition) 
  scope_after_update(definition).contains?(record_before_update)
end
old_record_in_old_scope?(definition) click to toggle source
# File lib/render_sync/model_change_tracking.rb, line 80
def old_record_in_old_scope?(definition)
  @scopes_before_update[definition.name][:contains_record]
end
record_after_update() click to toggle source
# File lib/render_sync/model_change_tracking.rb, line 64
def record_after_update
  self
end
record_before_update() click to toggle source

Return the instance (state) of this record from before the update (which was previously stored by store_state_before_update)

# File lib/render_sync/model_change_tracking.rb, line 60
def record_before_update
  @record_before_update
end
remained_in_old_scope?(definition) click to toggle source
# File lib/render_sync/model_change_tracking.rb, line 68
def remained_in_old_scope?(definition)
  old_record_in_old_scope?(definition) && new_record_in_old_scope?(definition)
end
scope_after_update(definition) click to toggle source
# File lib/render_sync/model_change_tracking.rb, line 76
def scope_after_update(definition)
  RenderSync::Scope.new_from_model(definition, record_after_update)
end
scope_before_update(definition) click to toggle source
# File lib/render_sync/model_change_tracking.rb, line 72
def scope_before_update(definition)
  @scopes_before_update[definition.name][:scope]
end
store_state_before_update() click to toggle source

Stores the current state of the record with its attributes and all sync relations in an instance variable BEFORE the update command to later be able to check if the record has been added/removed from sync scopes.

Uses ActiveModel::Dirty to track attribute changes (triggered by AR Callback before_update)

# File lib/render_sync/model_change_tracking.rb, line 20
def store_state_before_update
  record = self.dup
  changed_attributes.each do |key, value|
    record.send("#{key}=", value)
  end
  record.send("#{self.class.primary_key}=", self.send(self.class.primary_key))
  
  @record_before_update = record
  
  @scopes_before_update = {}
  sync_scope_definitions.each do |definition|
    scope = RenderSync::Scope.new_from_model(definition, record)
    @scopes_before_update[definition.name] = { 
      scope: scope, 
      contains_record: scope.contains?(record) 
    }
  end
end