Class: Hecks::Facade::Handle

Inherits:
Object
  • Object
show all
Defined in:
lib/hecks/facade/handle.rb

Overview

ONE record in hand — the object Pizza.create_pizza(...) and Pizza.find(id) give back.

ONE SHARED CLASS, not one minted per aggregate. The old door subclassed Hecks::Aggregate per head and defined a reader per field ; this wraps the same Runtime::Instance state hash and answers readers and verbs through method_missing, closing over the dispatcher and the aggregate's IR — so a boot mints no classes at all, and two boots in one process each hand out handles bound to their own dispatcher.

A non-creating verb is a method returning self, so commands chain :

Pizza.create_pizza(...).add_topping(...).purchase(...)

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(dispatcher:, domain:, ir:, instance:) ⇒ Handle

Returns a new instance of Handle.



21
22
23
24
25
26
27
28
29
# File 'lib/hecks/facade/handle.rb', line 21

def initialize(dispatcher:, domain:, ir:, instance:)
  @dispatcher = dispatcher
  @domain     = domain
  @ir         = ir
  @id         = instance.id
  @state      = instance.state
  define_reference_accessors
  define_verb_methods
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(name, *args, **kwargs, &block) ⇒ Object

A declared field not yet written arrives here too (nil, the way a defined reader answered). Verbs are NOT handled here — see define_verb_methods for why.



75
76
77
78
79
# File 'lib/hecks/facade/handle.rb', line 75

def method_missing(name, *args, **kwargs, &block)
  return @state[name] if @state.key?(name) || reader?(name)

  super
end

Instance Attribute Details

#idObject (readonly)

Returns the value of attribute id.



19
20
21
# File 'lib/hecks/facade/handle.rb', line 19

def id
  @id
end

Instance Method Details

#==(other) ⇒ Object Also known as: eql?

Equality is (WHICH AGGREGATE, WHICH ID) — two handles to the same record are the same record, and a Pizza never equals an Account that happens to share an id. The old door said this with other.is_a?(self.class), leaning on one class per aggregate ; the fqn says it in data.



62
# File 'lib/hecks/facade/handle.rb', line 62

def ==(other) = other.is_a?(Handle) && other.fqn == fqn && other.id == @id

#[](key) ⇒ Object



31
# File 'lib/hecks/facade/handle.rb', line 31

def [](key) = @state[key.to_sym]

#eventsObject



48
49
50
# File 'lib/hecks/facade/handle.rb', line 48

def events
  @dispatcher.events.select { |event| event.aggregate == fqn && event.id == @id }
end

#fqnObject



46
# File 'lib/hecks/facade/handle.rb', line 46

def fqn = "#{@domain}::#{@ir.hecks_name}"

#hashObject



64
# File 'lib/hecks/facade/handle.rb', line 64

def hash = [Handle, fqn, @id].hash

#inspectObject Also known as: to_s



66
67
68
69
# File 'lib/hecks/facade/handle.rb', line 66

def inspect
  fields = @state.map { |key, value| "#{key}=#{value.inspect}" }.join(" ")
  "#<#{@ir.hecks_name} #{@id} #{fields}>"
end

#reloadObject



52
53
54
55
56
# File 'lib/hecks/facade/handle.rb', line 52

def reload
  stored = repository.find(@id)
  @state = stored.state if stored
  self
end

#respond_to_missing?(name, include_private = false) ⇒ Boolean

Returns:

  • (Boolean)


81
82
83
# File 'lib/hecks/facade/handle.rb', line 81

def respond_to_missing?(name, include_private = false)
  @state.key?(name) || reader?(name) || super
end

#to_hObject

id: @id LAST, not first — an aggregate is free to declare its own attribute literally named id (BurningManPrep's Item, attribute :id, ItemId, is real corpus now: identified_by :id reads THAT attribute for identity). When it does, @state[:id] holds the full wrapped value object, not the bare identity string — merging @state on top of { id: @id } let that wrapped VO silently clobber the correct bare @id, so every caller of to_h (the JSON door's own /api/:coll listing, in particular) got an object where a plain identity string belonged. @id merged LAST always wins, so to_h[:id] is always the true bare identity, regardless of whether the aggregate also happens to declare a same-named field.



44
# File 'lib/hecks/facade/handle.rb', line 44

def to_h = @state.merge(id: @id)