Skip to content

Instantly share code, notes, and snippets.

@arnewauters
Created February 2, 2015 16:42
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save arnewauters/782f8363f4e1fc6d5232 to your computer and use it in GitHub Desktop.
Save arnewauters/782f8363f4e1fc6d5232 to your computer and use it in GitHub Desktop.
Braindump CQRS
# CLIENT (if RAILS)
class ChangeTreatmentForm
include ActiveModel::Model
attr_reader :reason, :episode_id, :new_treament_id
validate :reason, :episode_id, :new_treatment_id present: true
def to_command
ChangeTreatmentCommand.new(@new_treatment_id, @episode_id, @reason)
end
end
# SERVER
class EpisodesController
def treatment
form = ChangeTreatmentForm.new(params)
result = ChangeTreatmentHandler.new(form.to_command).call
head :ok if result
end
end
class ChangeTreatmentCommand < Struct.new(:new_treatment_id, :episode_id, :reason)
end
class BaseHandler
pattr :command
def initialize(command)
@command = command
end
def call
authorize @command.to_s
ActiveRecord::Base.transaction do
perform
redis.LPUSH(:commands, @command) # => RAW event store
end
end
protected
def perform
raise "IMPLEMENT SOMETHING"
end
end
class ChangeTreatmentHandler < BaseHandler
def perform
episode = Episode.find(command.episode_id)
episode.complete(command.reason)
episode.save!
Episode.create!(
patient_id: episode.patient_id,
treatment_id: command.new_treatment_id
)
end
end
class Episode < ActiveRecord::Base
def complete(reason)
self.ended_at = Time.current
self.reason = reason
# Synchronous, part of the domain operation
Planning.clear_episode(self.id)
# Asynchronous, part of the domain operation
ClearPlanningJob.new(self.id).perform_later
# Synchronous / Asynchronous (up to the handler), NOT part of the domain operation
Whisper.broadcast(:episode_completed, self.id)
end
end
Whisper.subscribe(:episode_completed, EpisodeCompletedHandler)
class EpisodeCompletedHandler
def call
# Mail some doctor
# Print something ...
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment