Last active
February 6, 2025 17:07
-
-
Save wassson/d000043d5960c5903cb000e31583da2b to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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