Skip to content

Instantly share code, notes, and snippets.

@wassson
Last active February 6, 2025 17:07
Show Gist options
  • Save wassson/d000043d5960c5903cb000e31583da2b to your computer and use it in GitHub Desktop.
Save wassson/d000043d5960c5903cb000e31583da2b to your computer and use it in GitHub Desktop.
# Pseudocode for Interactor pattern
class PurchaseRecordsController
def create
purchase_order = PurchaseOrder.find id
# Call the organizer and pass some state
# purchase_order can be accessed in any of the Interactors called in
# the ReceivePurchaseOrder organizer
result = ReceivePurchaseOrder.call(purchase_order: purchase_order)
if result.success?
# Access the purchase record through result.purchase_record
puts "PurchaseRecord created successfully!"
else
puts "Error: #{result.message}"
end
end
end
class ReceivePurchaseOrder
include Interactor::Organizer
# Runs these classes in the defined order
# if one fails, all of the previous classes will
# run their 'rollback' functions in the reverse order.
organize CreatePurchaseRecordInteractor,
CreateStockLineItemInteractor,
IdentifyNeededPartsInteractor,
AllocateStockToPartsInteractor
end
class CreatePurchaseRecordInteractor
include Interactor
def call
if purchase_record = purchase_order.purchase_record.create(...)
# Use 'context' to store state between Interactors
context.purchase_record = purchase_record
else
context.fail!(message: "Failed to create Purchase Record for: #{purchase_order}")
end
end
# rollback is called automatically if an Interactor in the chain fails
def rollback
context.purchase_record.delete
end
end
class CreateStockLineItemInteractor
include Interactor
def call
stock_line_item = purchase_order.stock_line_item.create(...)
context.stock_line_item = stock_line_item
end
def rollback
context.stock_line_item.delete
end
end
class IdentifyNeededPartsInteractor
include Interactor
def call
parts = Part.where('quantity_needed > 0') # obviously missing some details in this query
context.parts = parts if parts
end
def rollback
context.parts.delete_all
end
end
class AllocateStockToPartsInteractor
include Interactor
def call
if context.parts
parts.each do |part|
part_quantity = part.quantity
part_line_item = part.part_line_items.create(...)
context.part_line_items << part_line_item
context.stock_line_item.quantity -= part_quantity
end
end
end
def rollback
context.part_line_items.delete_all
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment