Class: GraphMediator::Mediator

Inherits:
Object
  • Object
show all
Includes:
AASM
Defined in:
lib/graph_mediator/mediator.rb

Overview

Instances of this class perform the actual mediation work on behalf of a Proxy#mediated_transaction.

Defined Under Namespace

Classes: ChangesHash, IndexedHash

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(instance) ⇒ Mediator

Returns a new instance of Mediator.

Raises:

  • (ArgumentError)


152
153
154
155
156
157
# File 'lib/graph_mediator/mediator.rb', line 152

def initialize(instance)
  raise(ArgumentError, "Given instance has not been initialized for mediation: #{instance}") unless instance.kind_of?(GraphMediator)
  self.mediated_instance = instance
  self.changes = ChangesHash.new
  self.stack = []
end

Instance Attribute Details

#changesObject

Changes made to mediated_instance or dependents during a transaction.



128
129
130
# File 'lib/graph_mediator/mediator.rb', line 128

def changes
  @changes
end

#mediated_instanceObject

An instance of the root ActiveRecord object currently under mediation.



125
126
127
# File 'lib/graph_mediator/mediator.rb', line 125

def mediated_instance
  @mediated_instance
end

#stackObject

Tracks nested transactions



131
132
133
# File 'lib/graph_mediator/mediator.rb', line 131

def stack
  @stack
end

Instance Method Details

#mediate(&block) ⇒ Object



181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
# File 'lib/graph_mediator/mediator.rb', line 181

def mediate(&block)
  debug("mediate called")
  stack.push(self)
  result = if idle?
    begin_transaction &block
  else
    debug("nested transaction; mediate yielding instead")
    yield self
  end
  debug("mediate finished successfully")
  return result

ensure
  done! unless nested? # very important, so that calling methods can ensure cleanup
  stack.pop
end

#mediated_idObject

The id of the instance we are mediating.



166
167
168
# File 'lib/graph_mediator/mediator.rb', line 166

def mediated_id
  mediated_instance.try(:id)
end

#mediation_enabled?Boolean

Mediation may be disabled at either the Class or instance level. TODO - global module setting?

Returns:

  • (Boolean)


161
162
163
# File 'lib/graph_mediator/mediator.rb', line 161

def mediation_enabled?
  mediated_instance.mediation_enabled?
end

#nested?Boolean

True if we are currently in a nested mediated transaction call.

Returns:

  • (Boolean)


177
178
179
# File 'lib/graph_mediator/mediator.rb', line 177

def nested?
  stack.size > 1
end

#refresh_mediated_instanceObject

Reload the mediated instance. Throws an ActiveRecord::StaleObjectError if lock_column has been updated outside of transaction.



206
207
208
209
210
211
212
213
214
215
216
217
# File 'lib/graph_mediator/mediator.rb', line 206

def refresh_mediated_instance
  debug "refresh_mediated_instance called"
  unless mediated_instance.new_record?
    if mediated_instance.locking_enabled_without_mediation?
      locking_column = mediated_instance.class.locking_column
      current_lock_version = mediated_instance.send(locking_column) if locking_column
    end
    debug("reloading")
    mediated_instance.reload 
    raise(ActiveRecord::StaleObjectError) if current_lock_version && current_lock_version != mediated_instance.send(locking_column)
  end
end

#track_changes_for(ar_instance) ⇒ Object

Record the ActiveRecord changes state of the current object. This allows us to make decisions in after_mediation callbacks based on changed state.



172
173
174
# File 'lib/graph_mediator/mediator.rb', line 172

def track_changes_for(ar_instance)
  changes << ar_instance
end