Sunday, November 8, 2015

Legacy Prawns

Ok, so I am coming to the close of my annual deployment of my Competition Manager application.

Right now registration is closed and the actual competition will happen this Friday.

In a way this is a bitter sweet time. In one way I am excited to see the culmination of my effort, but in another way it is a distraction to the other projects I am working on.

The project is a legacy app using Ruby on Rails version 3.2. I know I should update it to the latest version of Rails, but since it is not a paying project it’s hard to justify the effort.

At any rate, when the actual competition occurs this Friday, everything must work seemlessly, as the competition occurs over about 20 hours and all the scores and results must be collected, entered, calculated and reported on during that time.

This is the critical time for Competition Manager as there really is no time to fix any bugs if they were to arise.

So I was doing my due dilligence by testing the scoring and reporting modules of the application yesterday and I realized there was an annoyance for the scorekeepers I should try to address.

In the past after the scores for an event were entered, the user would save the scores and print the report. This caused a pdf file to be downloaded and shown in the browser.

Unfortunately this takes the scorer out of the application and forces them to save the report manually for later printing or print it right then.

I figured a better approach would be to download the file to the scorer’s computer as a separate pdf file without taking them out of the screen they were on. That way they could deal with all the reports at one time.

To do this I needed to do two things:
1. Give each event report a separate file name
2. Download the report instead of opening it in a separate browser window.

So this takes me to the crux of this post. My overall intent of these posts is to document things I learned or had to research to solve so that I, for one, won’t have to re-learn the issue again and maybe also in the process it will help others.

Competition Manager uses an older gem called “prawn” for it’s pdf generation and “prawnto” to support templates.

Yes I know there are better solutions and even “prawn” has a new version but one week out from the actual competition I am not about to change out a major component of the product.

So I had to figure out how to fix this with the current legacy code.

The way this works is I have a route set up to serve the reports that once called retrieves the correct data for the report then uses prawnto to load the template and generate the pdf. The original controller method looked like this:

   def event_results
       @event = Event.find(params[:event_id])
   end

So what would happen is the client would call this method with the event id and then the template named “event_results.pdf.prawn” would be used to generate the pdf file that was then returned to the client.

I knew I needed to set the filename and stream the file back to the client, setting the correct headers, but how to do it was hard to find. Here is what I eventually found that would work:

  def event_results
      @event = Event.find(params[:event_id])
      prawnto :filename => @event.name + ".pdf", :inline => false, :template => "event_results.pdf.prawn"
  end

So now what happens is the filename is set to the name of the event (with a .pdf extension), it is marked as inline false so the document will be downloaded, and finally the template to generate is specified.

So in the end a one line change solved the problem. I tested it, deployed it and the product is ready for action this Friday.

Till next time.

No comments:

Post a Comment