On a recent Rails project two dozen models and sixty associations were needed to drive the application. A medium sized effort. However, it's tough to talk users through the complexity when the need arises, even when you're just dealing with a small chunk. After drawing circles and arrows on whiteboards too many times, I decided to mechanize.
I'd used Railroad (a great rubygem written by Javier Smaldone) a few times before to document smaller projects. It loads models and controllers from a rails project and renders everything in 'dot' format that can be processed by graphviz, an open source graph rendering framework. I railroaded the app and quickly had diagrams in hand. Happiness all around.
But there were a few things I noticed as I talked around the pictures. I needed colors. And labels. And fewer circles and arrows. I decided to take a dive into the railroad code and add some features.
What I eventually ended up with was a considerable set of changes.
Changes to Allow Subgraphing
Often I didn't want to see the whole graph at once. What I wanted was the ability to include only the models I listed, or exclude a set of models from the whole. After implementing this, I decided I also wanted the ability to focus on a set of nodes, including them and any other directly-connected nodes.
By using -F, -E and -I in combination, a logical subset of the model can be displayed fairly easily.
Model Node Content Display Changes
I found that I sometimes needed more or less information in a displayed node. Brief mode was already present (for just displaying the class name in a node) but I wanted a little more content control.
Using -B with -F turned out to be a great way to present information. I could see what was being focused upon in context, without extraneous detail.
Changes to Association Display
I found I needed to be able to show different associations differently. Conventional Rails associations were fine, left black and unlabeled. But polymorphic associations, many-to-many through relationships, and unconventionally named associations needed different labels and colors. By default, I decided to always display these and provide methods to hide them.
Multiple Diagrams at Once
Once the rest was done and I'd used it all for a while, I decided that automatically generating a focused diagram for each model would save me a lot of time.
A simple rake task completed the automation:
@railroad_command = Config::CONFIG["target_vendor"] == 'pc' ?
'railroad.bat' : 'railroad'
task :graphs do
FileUtils.mkdir_p 'graphs'
`#{@railroad_command} -M -b -o graphs/_overview.dot`
`#{@railroad_command} -M -B -O graphs/`
FileUtils.cd 'graphs' do
FileList['*.dot'].each do |f|
`dot -Tpng #{f} -o #{f.gsub(/dot$/,"png")}`
end
end
end
Finally, I refactored the completed code, DRYing out the iterative changes I'd made.What I now have is a nice, simple way to produce diagrams of the database and associations between tables for discussion and documentation. I submitted the patch to Javier and hopefully it will be integrated into the railroad trunk fairly soon. You can grab railroad-0.5.0 and the patch and play with it if you want by downloading it from rubyforge.
4 comments:
Nice enhancement! How do I apply the patch you posted on Rubyforge? Could you please list detailed steps to apply the patch?
I tried GNU's patch.exe for Windows and was not successful.
Thanks again...
The patch was made with Unix diff, which should be able to apply the changes to local files. Diff is the way I used to do this stuff way back before good version control...
This is exactly what I need for my rails app. I've got like 30 models and I need a way to exclude most of them so my graph won't look so busy.
Sadly though, I couldn't get your patch to work. I think the line numbers don't line up with my version of railroad (0.5.0).
Hmmm... perhaps I should just post my working version somewhere?
Post a Comment