module RailsEventSourcing::Command

The Base command mixin that commands include.

A Command has the following public api.

“‘

MyCommand.call(user: ..., post: ...) # shorthand to initialize, validate and execute the command
command = MyCommand.new(user: ..., post: ...)
command.valid? # true or false
command.errors # +> <ActiveModel::Errors ... >
command.call # validate and execute the command

“‘

‘call` will raise an `ActiveRecord::RecordInvalid` error if it fails validations.

Commands including the ‘RailsEventSourcing::Command` mixin must:

Ex:

“‘

class MyCommand
  include RailsEventSourcing::Command

  attributes :user, :post

  def build_event
    Event.new(...)
  end
end

“‘

Public Instance Methods

attributes(*args) click to toggle source

Define the attributes. They are set when initializing the command as keyword arguments and are all accessible as getter methods.

ex: ‘attributes :post, :user, :ability`

# File lib/rails-event-sourcing/command.rb, line 57
      def attributes(*args)
        attr_reader(*args)

        initialize_method_arguments = args.map { |arg| "#{arg}:" }.join(', ')
        initialize_method_body = args.map { |arg| "@#{arg} = #{arg}" }.join(";")
        initialize_definition = <<~CODE
          def initialize(#{initialize_method_arguments})
            #{initialize_method_body}
            after_initialize
          end
        CODE

        class_eval(initialize_definition)
      end
call(*args) click to toggle source

Run validations and persist the event.

On success: returns the event On noop: returns nil On failure: raise an ActiveRecord::RecordInvalid error

# File lib/rails-event-sourcing/command.rb, line 48
def call(*args)
  new(*args).call
end
event() click to toggle source

A new record or nil if noop

# File lib/rails-event-sourcing/command.rb, line 84
def event
  @event ||= (noop? ? nil : build_event)
end
noop?() click to toggle source
# File lib/rails-event-sourcing/command.rb, line 88
def noop?
  false
end

Private Instance Methods

after_initialize() click to toggle source

Hook to set default values

# File lib/rails-event-sourcing/command.rb, line 106
def after_initialize
  # noop
end
build_event() click to toggle source

Returns a new event record or nil if noop

# File lib/rails-event-sourcing/command.rb, line 101
def build_event
  raise NotImplementedError
end
execute!() click to toggle source

Save the event. Should not be overwritten by the command as side effects should be implemented via Reactors triggering other Events.

# File lib/rails-event-sourcing/command.rb, line 96
def execute!
  event.save!
end