Module: ActiveShepherd::AggregateRoot

Defined in:
lib/active_shepherd/aggregate_root.rb

Defined Under Namespace

Modules: ClassMethods

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.included(base) ⇒ Object



2
3
4
# File 'lib/active_shepherd/aggregate_root.rb', line 2

def self.included(base)
  base.extend(ClassMethods)
end

Instance Method Details

#aggregate_changesObject

Public: Returns the list of changes to the aggregate that would persist if #save were called on the aggregate root.

Examples

@project.aggregate_changes
# => { name: ["Clean House", "Clean My House"], todos: [{ text: ["Take out trash", "Take out the trash" ...

Returns all changes in the aggregate



52
53
54
# File 'lib/active_shepherd/aggregate_root.rb', line 52

def aggregate_changes
  ActiveShepherd::Methods::QueryChanges.query_changes aggregate
end

#aggregate_changes=(changes) ⇒ Object

Public: Given a serializable blob of changes (Hash, Array, and String) objects, apply those changes to

Examples:

@project.aggregate_changes = { name: ["Clean House", "Clean My House"] }

Returns nothing. Raises ActiveShepherd::InvalidChangesError if the changes supplied do not

pass #valid_aggregate_changes? (see below)

Raises ActiveShepherd::BadChangeError if a particular attribute change

cannot be applied.

Raises an ActiveShepherd::AggregateMismatchError if any objects in the

aggregate are being asked to change attributes that do not exist.


26
27
28
29
30
31
32
33
34
35
36
# File 'lib/active_shepherd/aggregate_root.rb', line 26

def aggregate_changes=(changes)
  changes_errors = ActiveShepherd::ChangesValidator.new(self).validate changes
  unless changes_errors.empty?
    raise ActiveShepherd::InvalidChangesError, "changes hash is invalid: "\
      "#{changes_errors.join(', ')}"
  end
  # The validation process actually runs the changes internally. This means
  # we don't have to explicitly invoke # #apply_changes here.
  # XXX: remove when ChangesValidator does this
  ActiveShepherd::Methods::ApplyChanges.apply_changes aggregate, changes
end

#aggregate_stateObject

Public: Returns the entire state of the aggregate as a serializable blob. All id values (primary keys) are extracted.

Examples

@project.aggregate_state
# => { name: "Clean House", todos: [{ text: "Take out trash" ...

Returns serializable blob.



78
79
80
# File 'lib/active_shepherd/aggregate_root.rb', line 78

def aggregate_state
  ActiveShepherd::Methods::QueryState.query_state aggregate
end

#aggregate_state=(blob) ⇒ Object

Public: Injects the entire state of the aggregate from a serializable blob.

Examples:

@project.aggregate_state = { name: "Clean House", todos: [{ text: "Take out trash" ...

Returns nothing. Raises an AggregateMismatchError if the blob contains references to objects

or attributes that do not exist in this aggregate.


65
66
67
# File 'lib/active_shepherd/aggregate_root.rb', line 65

def aggregate_state=(blob)
  ActiveShepherd::Methods::ApplyState.apply_state aggregate, blob
end

#reload_aggregateObject

Public: Reloads the entire aggregate by invoking #reload on each of the records in the aggregate.



84
85
86
87
# File 'lib/active_shepherd/aggregate_root.rb', line 84

def reload_aggregate
  reload
  raise "NYI"
end

#reverse_aggregate_changes=(changes) ⇒ Object

Public: Reverses the effect of #aggregate_changes=



39
40
41
# File 'lib/active_shepherd/aggregate_root.rb', line 39

def reverse_aggregate_changes=(changes)
  self.aggregate_changes = ActiveShepherd::DeepReverseChanges.new(changes).reverse
end

#valid_aggregate_changes?(changes, emit_boolean = true) ⇒ Boolean

Public: Validates a set of changes for the aggregate root.

* Does deep_reverse(deep_reverse(changes)) == changes?
* Assuming the model is currently valid, if the changes were applied,
  would the aggregate be valid?
* If I apply the changes, and then apply deep_reverse(changes), does
  #aggregate_state change?

See ActiveShepherd.deep_reverse

Examples:

@project.valid_aggregate_changes?(@project.aggregate_changes)
# => true

Returns true if and only if the supplied changes pass muster.

Returns:

  • (Boolean)


105
106
107
108
109
110
111
# File 'lib/active_shepherd/aggregate_root.rb', line 105

def valid_aggregate_changes?(changes, emit_boolean = true)
  validator = ActiveShepherd::ChangesValidator.new(self)
  errors = validator.validate changes
  emit_boolean ? errors.blank? : errors
ensure
  reload_aggregate
end