This message was imported from the Ruby/Rails Modularity Slack server. Find more info in the import thread.
After spending a couple of weeks pretty much focused on hand-picking files from our main app to move into new/existing packs, deciding a layer for each of those packs and so on… I’ve just confirmed what we all know already: this is hard stuff and it takes longer than we want. But then an idea came to mind… do you think it would be possible to leverage the nice tooling they guys at Gusto have created… to try and automate something around this?
I’m not talking about something perfect. Not even close. But something to start with. Something that could analyze the existing dependencies in a monolith via packwerk and then suggest the set of X packs that would throw the least amount of violations/todos… . The resulting architecture might not reflect the reality of the project from a business POV, but it would from the POV of the existing code. This could mean less work to take it from there to a point where the process to transition into a better architecture is done with less “noise”. I might be just dreaming an impossible here…
I guess I first need to learn more about neo4j or some other graph theory-related tool and… and… convince some key stake-holders that it’s ok for me to reserve a bunch of time for this
If it’s helpful, here was the rake task I put together. Guessing it can be improved but I am a noob at graph dbs as well
desc "Send ActiveRecord models and their associations to Neo4j for visualization"
task neo4j_relations: :environment do
# Eager load all application classes (including models)
Rails.application.eager_load!
driver = Neo4j::Driver::GraphDatabase.driver('<bolt://localhost:7687>') # replace with your Neo4j configuration
ActiveRecord::Base.descendants.each do |model|
next if model.abstract_class?
session = driver.session
session.write_transaction do |tx|
tx.run("CREATE (a:Model {name: '#{model.name}'})") # Create nodes for each model
model.reflections.each do |name, reflection|
target_model = reflection.class_name
relation = reflection.macro.to_s
# Create relationships between models
tx.run("MATCH (a:Model {name: '#{model.name}'}), (b:Model {name: '#{target_model}'})
MERGE (a)-[r:#{relation.upcase}]->(b)")
end
end
session.close
end
end