The idea would be to remove all the after_create
/ after_update
hooks in our Active Record models and replace them with created_{ModelName}
/ updated_{ModelName}
events containing the new model attributes.
For example
class User < ApplicationRecord
after_create :set_collaboration
after_create :add_interests
after_create :create_stat_record
after_update :admin_chat_to_do
after_update :create_stat_record
end
would become
class User < ApplicationRecord
after_create :publish_created_user_event
after_update :publish_updated_user_event
def publish_created_user_event
publish_user_event(save_mode: "created")
end
def publish_updated_user_event
publish_user_event(save_mode: "updated")
end
def publish_user_event(save_mode:)
EventClient.publish(
topic: "#{save_mode}_user",
data: self.attributes,
)
end
end
The next stage of the implementation would be to invert the dependencies by allowing workers to subscribe to these events. Then the business logic that used to live in the Active Record model after action methods could be moved into bespoke Service classes that the workers could call based on the Event topic.
class BackgroundEventWorker
def self.route(event)
ServiceFactory.for(event).call(event)
end
class ServiceFactory
def self.for(event)
case event[:topic]
when 'created_user'
CreatedUserService
when 'updated_user'
UpdatedUserService
else
->(event) {}
end
end
end
end