Peter Marklund's Home

Peter on Rails

We just launched a new website for We+ at www.weplus.se. The website is available in both a swedish and english version and is responsive. Please check it out and let us know if you think We+ would be a good fit for your company!

This autumn I have joined We+ - a new exciting startup in the exercise and health area. Our product uses the power of small groups and positive peer pressure to promote exercise among employees. We have already built a first version of the system and done Alpha testing and this week we are kicking off a pilot with two large swedish companies. Exciting!

I'm really happy to see how Rails continues to evolve through thousands of small improvements, many of which are features which I know would have been useful in projects I have worked on in the past. I hope to be able to cover some of the new stuff in Rails 4 later.

We have a great job opening right now for Ruby developers at Mag+. Mag+ helps bring magazines and other publications (such as the IKEA catalogue) to the iPad and other tablets. Please check out the job ad if you are interested.

I'm giving a series of two day introductory Ruby courses to C++ programers at Ericsson here in Stockholm and I've made the course material available on Github. The course material includes slides (keynote and pdf) as well as Ruby code examples. For the exercise part I am relying on the Ruby Koans and they have been much appreciated.

I enjoy being back in the teacher role and I hope to be able to teach courses like this many times again in the future.

The value NULL in a relational database represents the absence of a value. Empty text fields and text areas in HTML forms on the other hand get submitted in Rails as empty strings. This means you can easily end up with empty strings in the database where you would expect NULL values. I came up with the following workaround for our ActiveRecord models:

We upgraded from Rails 3.0.1 to Rails 3.0.3 yesterday and sadly this broke file uploads for us in production. What do we conclude from this other than that we are missing integration tests for file uploads? Well, one noteworthy thing is that the Rails 3.0.3 release is not quite as backwards compatible as announced, at least not when it comes to file uploads. In Rails file fields in multipart forms are exposed in the params hash as an ActionDispatch::Http::UploadedFile object. As of a commit by tenderlove on the 5:th of October this class no longer inherits from Tempfile but instead delegates to Tempfile (i.e. tenderlove favored composition over inheritance like the GoF prescribes). Unfortunately, the UploadedFile class only delegates a handful of methods and not two important methods that we happened to be using, namely open and path. So now, for example when getting the path of the tempfile we have to fetch the tempfile first:

Is it worthwhile testing Rails ActiveRecord migrations? After all, they are only intended to be run once so regression testing isn't an issue. I honestly haven't tested my migrations much in the past but I recently decided to give it a try. I was surprised by the fact that it wasn't very different from testing any other part of my application. My test didn't end up having very good coverage so I still needed to test the migration manually. As usual when writing tests, I found that it drove a series of extract method refactorings. I went from having all code in the up method to having five shorter methods. A different approach to migration testing is to add sanity checks at the end of migrations that output an error message in production if the outcome of the migration wasn't what was expected.

One of the features I miss from Capistrano is the ability to easily do rollbacks when deploying to Heroku. What you can easily do though is git tag your releases and then do a rollback by pushing the previous release tag. I've created a RubyGem called heroku_release that does this. The gem has a few additional features such as the ability to generate a CHANGELOG file from the release tags and their comments. I also use it to generate a version file so that I can check on the live server what version of the code it is running.

It's interesting to note that Heroku is apparently working on supporting release management and logging - two problems I have ended up rolling my own solutions for recently. I look forward to seeing what they have come up with.

It can get really tiresome and repetitive to do debug printouts with puts. I've created a simple RubyGem called
debug_log that gives you a convenient way of evaluating and printing variables and other Ruby expressions
that you want to debug. Here is an example:

It's funny how I created this gem pretty much at the same time as Niclas Nilsson created his dp gem.
I owe the approach to patching the binding object to Niclas. I think that is a beautiful solution as it avoids you having to pass the binding object as an argument.

Mocks and stubs can be fragile and come back and bite you when they can get out of sync with your code. One way this can happen is that a method is renamed or you misspell the method name. To avoid this issue you can configure Mocha to disallow stubbing and mocking of non-existent methods. I've come up with two new methods for the cases where you are working with messages implemented with method_missing:

It is interesting to note that this extension of Mocha is possible because of its flexible and clever design. Mocha was recently updated to version 0.9.9. I am grateful to James Mead (Floehopper) for providing this excellent testing library.

Prompted by the fact that Heroku doesn't keep the Rails request logs around I went out looking for a logging solution. What I've ended up with is Request Log - a simple RubyGem for logging web requests to MongoDB.

My experiences with logging to MongoDB so far have been very positive. I see big potential in logging web requests to a database. The reason MongoDB is so well suited for the task is its high performance and strong query capabilities. This allows you to do advanced queries such as "give me all requests in this time period, with this response, status, this execution time, these parameters etc.". Each web request becomes a document in MongoDB and if you choose your database fields wisely you have a great tool at your disposal for statistics, monitoring, and debugging etc.

I'm curious to see how we'll be able to design and use our web request logs in the project I'm currently in. I'll report back here any interesting findings that we make.

I gave a presentation tonight entitled "Minimizing Library Dependencies" at the Stockholm Ruby User Group (SHRUG) meeting. The event was hosted by MediaPilot and sponsored (with beer) by Auktionskompaniet and it turned out to be a huge success with 73 registered attendees, great presentations and atmosphere. I talked to David Wennergren about hosting the next meetup and our ambition is to have about one per quarter. It's great to see the community coming to life again!

As part of an ongoing effort to offload out database at MyNewsdesk I have released a new Rails plugin called Cachable Model. The plugin is similar to an older plugin called Cached Model in that it basically caches primary key id lookups for ActiveRecord models. The Cachable Model plugin has an extra feature that lets you cache lookups by other unique columns as well. Here is an example:

Fred Brooks is a Computer Science professor who managed 5000 man-year IT projects at IBM in the sixties. His words carry a lot of weight and he certainly has something profound to say about software engineering. The central theme of the book is that of conceptual integrity. It's about the need to have a single architect, a master mind, who oversees all development and makes sure all the parts fit together. "A clean, elegant programming product must present to each of its users a coherent mental model of the application". The ideal scenario for conceptual integrity naturally is having a single programmer. The problem is that some systems are so big that in order to finish them before they are obsolete you need a large number of developers. Much of the book is spent discussing this difficult problem. How do you organize huge developer teams?

This weekend I taught a three day Ruby on Rails course here in Rome in Italy. It was a great experience and the people down here have shown the greatest hospitality and have taken very well care of me.

The format of the course was like a workshop with a small group of participants in a private and relaxed setting. I used my course material as a starting point and a road map but then improvised a lot and ended up doing a lot of hands on programming. Basically the course was divided into three parts:

Ruby and Rails fundamentals. A lot of time was spent on the programming language itself and we toured the features of Ruby by live coding in TextMate.

Writing a demo application. Similar to the AWR book, I built the basics for a store application, including file upload, advanced ActiveRecord associations, and deployment to a VPS with Capistrano.

The participants got to work on different features in the application. Time was also spent code reviewing the participants own Rails applications.

Overall I must say the course was quite a success. Every time I teach a course I look for ways to make my courses more interactive, more hands on, and more tailored to the needs of the participants.

I also had a great time outside the course in Rome - a city that I fell in love with immediately.