Since 1998 I have been privileged to have many very young and very bright minds from the University of New Haven’s Computer Science program work at my consulting business, BTree Technology. Using various programming languages of the day (VB in 1988, C++ in 2000, C# in 2002 and of course Ruby since 2004), I have set many programmers on a single simply-stated quest: to write good reports!
Oddly enough, while the focus has been reporting for dental office operations, this seemingly simple task was enough for me to realize that what I thought should be simple and quick – namely to write reports or small applications that manipulate data into specific reports – actually takes a long time to do well and makes for somewhat frustrating programming. Reporting does not have the glamour of a NASA rover project.
As with all programming, we struggle with a large disconnect between the person asking for the report and the programmer writing the report. Actually, since the person asking for the report has almost certainly never programmed, and almost certainly does not know SQL, they think it is easy to do! This makes the disconnect even worse than when writing applications, where the business logic people at least expect it to be a significant process, and not a couple of hours’ work. Even with 15 years of CS background, I managed to underestimate the complexity of a “simple report request.” If you asked my programmers how many times I cheerfully wandered into their studio and asked in vain, “Is it done yet?”, they would tell you that I used that phrase a bit too much.
When writing good reports, the ambiguities in the spec must be ironed out and the data, its summary, and the various views of the data that comprise the report must be verified. This involves more than making sure that the report is working bug free; it includes validating that the programmer understood what the report was for, that the data being presented is the data that was desired, that it is formatted correctly, that it is summarized correctly, and that it can be easily manipulated into other views such as graphs, charts, and other summary forms.
The frameworks available to me in 2004 were all fine choices for reporting but they also operated more as applications than as languages. That made some seemingly easy tasks very difficult, and as a result we had to do pre-processing of report data in VB and C# before it could be displayed nicely by Access, or in a .Net application. This was especially common when data was coming from two different sources, such as two different databases, or maybe a database and a text file. Pre-processing could be done in Access or in Crystal Reports, but the code was often “this-particular-report-specific.” Every time there was another report to do, even when it was only slightly different, we were back at the drawing board trying to twist and shim data into a report suitable for use. With limited time and too many reports to do, many reports ultimately went unfinished. This made managing report development for a small business much harder than it should be.
Greg was at the University of New Haven and looking for work in 2004 when I was hiring. We tried to continue in C#, but it was painfully slow. Then Greg wrote some quick reports in Ruby in three hours and I was impressed. I had never seen a Windows program do much after only three hours! With Ruby, we were able to benefit from an active open source community. It seemed to me that since C# development was so frustrating to us that we should pursue a new course.
Initially, we did not set out to spend two years writing a library to do reporting in Ruby. We only set out to write a few reports using re-useable Ruby code, but that effort grew into Ruport. At first Ruport was an application that could be called as a library, but that design decision was limiting to us, as it wasn’t allowing us to use Ruby to its full potential. So we dropped the application part of Ruport and it became a library. This library forms the core of the Ruport gem that you see today.
Among the many wins we experienced along the way, I was excited by all the help we received from the first coding contest we sponsored, where we gave awards for helping to document the API and for writing small functions that enhanced the library. The tremendous support we garnered from the Ruby community (especially from the mailing list, which I read but never write on) really inspired me to believe that there was more to this project than simply torturing a CS student with the task of coding reports. It became very obvious to me very quickly that many programmers wish reporting chores could be made more simple, and I felt very good about pushing a very smart person like Greg to provide us with a small, incremental, solution towards that goal. Although it is technically true that I funded this project by hiring Greg, he has volunteered thousands of hours of his own time outside of the 10 hours a week he actually worked for me.
Mike Milner was really a godsend to us as he had experience with doing reporting in Rails, the use of which truly extended Ruport to the next level. Since Mike is paid to do reporting by the company he works for, his contributions have allowed Ruport to evolve past what I could have afforded to invest in this project. For Mike too, this has been a work of love, to whatever extent a reporting library can be loved. He has volunteered many hours of his time to Ruport and to the book effort, for which I am very grateful.
Though I have more plans for the project, I have been quiet about them as Greg and Mike added a ton of useful features and tightened integration with other important Ruby packages, and finally got Ruport to 1.0. They also dedicated most of 2007 to writing this book. With so much activity, the project seems to have a life of its own.
The process used to create the application you will learn in this book is what I call “report-centric” development. We started with a bunch of manual payroll reports that were duplicated in Rails. I have tremendous admiration for Greg Brown and Mike Milner, and for their dedication to getting this book finished. Among many tasks, they wrote an application (PayR) twice, first in Camping and then in Rails. This book is different because the code for a useful and real application is presented. This seems to be more useful than presenting simplistic examples that leave off just when things start to get tricky.
Please enjoy the book, join the Ruport mailing list, and make suggestions for improving Ruport.
Gregory Gibson