Copyright © 2010 The G String. All Rights Reserved. Snowblind by Themes by bavotasan.com. Powered by WordPress.
Ruby On Rails
I couldn’t defer it any longer, so its time I held my annual C.V. update. This year, I’ve been doing more web-agency work with Head London, working on a grocery website, a classroom presentation tool and a celebrity competitions website. I also worked on the redesign of the TouchLocal website and its sister project Wefinda.
Take a look at the latest C.V. on my cv page.
Continue Reading »I’m currently bug-fixing on a Rails project, and encountered the need to convert the default UTC date-formats into local times, seeing as we’re enjoying our extra hour in our glorious British summer time. The documentation is a little confusing on this point, but I found that a good solution is to keep UTC for use in the database, and to just convert the string representation in the front-end:
<%= some_model.created_at.in_time_zone(‘London’).to_s(:short) %>
This would be good enough to work with sorting, and finds too, provided you were a little careful about which date representation you were using. There is also the ability to change the timezone with Time.zone = “London”.
Continue Reading »I’m currently working on a project to develop a content management system for a leading publisher, that generates content for a DVD. The system, developed in Ruby on Rails, naturally has a significant amount of background processing to do, with various assets respresented with large, binary files, often requiring server-side processing. For instance, we have a need to re-size a file that contains the scanned image of a page in a book, and cut it up into individual tiles for use in a Google-maps-style map.
Previously, I had been using backgroundrb for background tasks in ruby quite happily in projects. I was wooed, however, by the design of the workling project, which works as an adapter between several background schedulers, including Starling. The main attraction was the ability to defer the decision of which background scheduler to use until the last possible moment (an important part of agile development), and to switch between different schedulers in different environments. Now, I use Spawn in development and Starling Background job in production. Best of all, I can use the NotRemoteRunner in test mode, which means I can run my tests synchronously, waiting for the results of execution, without changing any code or running a seperate background process.
A good theory- but like all things in life using working had its share of problems. First of all, due to an issue with memcache and rails 2.3, a customised configuration of workling is required, and not well covered by the documentation. Place these snippets in your environment file of choice.
For Spawn runner:
config.after_initialize do
require ‘memcache’
Workling::Remote::Runners::SpawnRunner.options = { :method => :spawn }
Workling::Remote.dispatcher = Workling::Remote::Runners::SpawnRunner.new
end
For NotRemoteRunnner (good for testing!)
config.after_initialize do
require ‘memcache’
Workling::Remote.dispatcher = Workling::Remote::Runners::NotRemoteRunner.new
end
For Starling
config.after_initialize do
Workling::Remote.dispatcher = Workling::Remote::Runners::StarlingRunner.new
end
But the real gotcha is when it comes to dealing with Files, or any IO object in Ruby, asynchronously. Because workling makes no assumptions about which background processor you are using, it will call on the Ruby Marshal class to send your objects to your worker class: which in the case of Starling could be a server on a completely different machine. In my case, handling image files with paperclip required sending a file over the wire, but the documentation is scant on this presumably common use case. The solution is to convert your File handle into a binary String, which can be sent over the wire.
file = File.open(“path_to_file”, “rb”)
file_data = file.read
HardWorker.async_foo(file: => file_data)
This will send the binary data to the HardWorker, which can handle it any way it likes. In my case, I used the RMagick library to read it in from a blob:
image_file = Magick::ImageList.new
image_file.from_blob(file_data)
Be warned! The Starling system is built upon memcache, which by design is hard-coded to limit its memory buckets to 1MB each. This has the effect of limiting any marshalled data to a workling worker using Starling to 1MB, which is going to be a problem if you’re dealing with hi-res images or video. In the end, I used background job for my production image processing needs.
The main thing I learnt from background processing though is that synchronously has a ‘h’ in it. I had to re-factor about five classes :/
Continue Reading »
Hubbub is a new deliveries service that rounds up notable local shops and provides a single shop-front for them all, allowing customers to pick from the best grub in their borough. Selected for their repute, their ethical standards and their quality, the Hubbub shops collectively offer an alternative to the homogenised offerings of the cartel supermarkets, bringing their individual flavour to their community over the web.
With a butcher, a baker, a and greengrocer in Hubbub’s first catchment area, it is feasible to get your week’s shopping on Hubbub, yet the up-market range of cakes, wines and chocolates means hosting your fancy dinner party won’t be tarnished by ‘taste the difference’ wrappers.
Currently, the site delivers only to Islington, London, with plans to expand to other London boroughs. The site is scoped entirely around these delivery zones, which determines what products and stores are displayed. One technical challenge of the site is ensuring that customers, stores, products, deliveries, refunds, orders and shopping baskets don’t drift from Islington to Fulham. (If you wish to try-out the website, try putting in the example postcode provided). Rails helps out by using nested routes to allow us to scope resources within an area, so that our URLs are always prefixed ‘in-your-area/:id’.
But this was no straightforward e-commerce shopping site. Partly down to the ambitious nature of the developers at Head London when planning the project, the site is a full-blown delivery management system that runs the entire Hubbub business, which is a genuine on-line company. The site has to be aware of what deliveries the Hubbub drivers are available to make, and track customer’s shopping baskets on the website to the delivery slots. These slots equate to hours in the day of the customer’s choosing, when they would like their goods to be delivered, and each have a capacity. So the checkout process has to be integrated with this system, to ensure that Hubbub can fulfil the orders the website is taking.
Hubbub also has a sophisticated payment mechanism, beyond the scope of most normal payment-processing use cases. Due to the nature of selling locally-sourced produce, some items may fluctuate in price from the point they are ordered to when they are delivered; items sold by weight such as meat and cheese may vary, especially when whole items are needed, such as a 1 kilogram chicken might actually vary depending on the individual bird. This plays havoc when coding a quantity, price and order total system, of which Hubbub has an elaborate variety of options for the administrators populating the database. To support this change in price, we take a nominal amount to verify the card, refund it and then process the order, which may have radically altered afterwards, some time after. Using SecureTrading and XPay, we were able to realise these special use cases, without compromising on security, and without storing sensitive credit card information. We built an open-source rails gem called breadmachine, which is capable of handing 3D-secure redirects and standard authorisations transparently.
Joining an in-progress project of this size was quite daunting. Given a use case or issue ticket, to comb through fifty model classes and determine what to change made for a steep learning curve. The complex object graph of Hubbub meant that making insular changes was difficult; sometimes a feature ran through the entire system meaning that sufficient tests for regression became an immediate need. We ditched the fixtures, which were becoming unmanageable, with NotaHat’s Machinist to mock the objects, trading the relative ease of object instantiation against an increased test suite running time.
Hubbub enters a busy and unproven, yet growing market of on-line groceries. Some have their doubts, but I think that this market has huge potential. When the quality of locally-sourced produce is considered, as well the environmental benefits, its easy to see on-line groceries go the way of the mobile applications market – initially an expensive and questionable area but eventually viable and sustainable.
Continue Reading »In my current Ruby on Rails project, I’m learning about Notahat’s machinist testing framework to build object graphs on which to write unit tests. Its a nice improvement on fixtures; using an object-orientated, programmatic approach to creating test data.
In the pursuit of 100% code coverage, I hit on a problem when trying to test UploadColumn, which was being used for handling images on a Product class. Normally in a Test::Unit class, I could invoke the fixture_file_upload method to simulate the multi-part form upload of an image, but in machinist I couldn’t do that. After finding next to nothing in the way of documentation for testing Upload column, I did some rummaging around in the gem and found the solution.
At the top of your blueprints file, include UploadColumn:
include UploadColumn
Then, in your blueprint, you can use the UploadedImage class to represent your uploaded image:
Product.blueprint do
title
description
image { UploadedFile.upload(File.new(RAILS_ROOT + ‘/test/fixtures/label.png’)) }
end
I hope that helps somebody…
