October 26th, 2007
Jeremy Kemper (aka bitsweat) committed a very useful tool into the Rails trunk not too long ago: a request profiler! It’s a human-friendly wrapper script around the ruby-prof library, a nice ruby code profiler, that lets you run multiple requests against a URI in your application and get a detailed code profile report in text and HTML.
Wanna try it out? Update your vendor/rails to at least revision 8016, run rake rails:update to copy the new script/performance/request script into your app’s script directory, install the ruby-prof gem (sudo gem install ruby-prof), then let it loose on your app.
The options are pretty simple, just pass the script the URI you wanna profile. There’re options for specifying how many requests you want to process, and for profiling POST requests, there’s one for
specifying a POST fixture file.
USAGE: script/performance/request uri [options]
-u, --uri [URI] Request URI. Defaults to http://localhost:3000/
-n, --times [0000] How many requests to process. Defaults to 1000.
-b, --benchmark Benchmark instead of profiling
--method [GET] HTTP request method. Defaults to GET.
--fixture [FILE] Path to POST fixture file
--open [CMD] Command to open profile results. Defaults to "open %s &"
-h, --help Show this help
At the end of the run, you get a text and HTML report with the methods called and the time spent in them. If you haven’t seen a code profile before, it looks something like this:
Very nice stuff! It’s extremely convenient to have profiling like this built into Rails itself - personally I’ve not even run any profiling on my Rails code because it seemed like a hassle (though I do run httperf benchmarks and take note the number of requests per second). With code profiling, you can easily see which parts of your code are the bottlenecks and optimize away - it’s a godsend that it’s so easy to do it in Rails!
Anyway, this is all still new stuff I imagine and subject to change (and improvements), but still very exciting for those of us who are hitting performance bottlenecks in our Rails apps (and are not already doing code profiling).
October 15th, 2007
You wouldn’t think that Konata Izumi (a character from the anime, Lucky Star) and Ruby on Rails (a web MVC framework) would somehow be associated, but they are!
I took the opportunity to fill in the missing ActiveRecord::Base#to_json documentation with examples using Konata Izumi and it got committed unchanged in revision 7905. Cute. I hope no one changes them.
Update: Managed to get more Konata Izumi documentation into Rails ;)
October 15th, 2007
One of my favorite foodie moments from my trip to Tokyo was at Harajuku where I had a crepe with cheese cake and ice cream from Angel’s Heart (need to dig that photo out). It was THE best crepe I’ve ever had. I’d even thrown around the idea of bringing it back to Singapore as a commercial venture.
Well anyway, I found that one of the crepe shops in Harajuku, Marion Cafe, that was just opposite Angel’s Heart, has opened a branch right here in Singapore at the IMM Building.
I tried their mango crepe (it had mango and ice cream in it) which set us back about SGD 5.80.
It was alright, not as good as the one I had in Harajuku of course, but still a nice treat. They have 105 different types of crepe - anything ranging for your run-of-the-mill strawberry and ice cream crepe, to tuna crepe, and even crepe with Japanese curry.
October 10th, 2007
The last time I wrote about ActiveRecord#to_json on edge Rails, it was missing some key functionality. For one, you couldn’t include any associations. Another thing was you couldn’t do something like this in your controller:
@authors = Author.find(:all)
render :json => @authors.to_json(:only => :name)
Oh and did I mention it wasn’t emitting valid JSON by default?
In the last few weeks, several patches to the Rails trunk have fixed all these issues (most of these patches are already on the Rails 2.0 Preview Release). JSON serialization of ActiveRecord objects is finally on par with XML serialization, and that old Jsonifier plugin I wrote can finally be sent off to the plugin retirement home (though, I am thinking of porting all the JSON patches into Jsonifier to add Rails 2.0-like JSON serialization to Rails 1.2.4, but who knows, I am lazy).
Anyway, back to the new JSON stuff on edge Rails.
No more invalid JSON from Rails
Yes it’s true. No more changing of module attribute to get Rails to produce valid JSON. Thanks to Choon Keat with his detailed SVN history snooping, we finally managed to get a patch to fix JSON encoding to quote all hash keys into Rails.
:include option can be used to include associations with ActiveRecord::Base#to_json
At DHH’s urging, I submitted a patch that added the :include option to ActiveRecord#to_json. Of course, it was a sloppy first submission and DHH pointed that out - a little bit of DRY love and it was really great to see it get committed (I have a soft spot for JSON serialization from Rails, since I’d been trying to achieve the same thing with Jsonifier).
So yes, now you can do:
json = @david.to_json(:include => :posts)
# or even...
json = @david.to_json(
:include => {
:posts => {
:include => {
:taggings => {
:include => {
:tag => { :only => :name }
}
}
}
}
})
Enumerable#to_json and Hash#to_json now accept options
One problem with Jsonifier that I often get emails about is how the to_json options don’t work for lists (Enumerables). And why is this important? Well, we often retrieve collections of ActiveRecord objects at a time with AR::B#find so it’s not too much to ask to be able to do this in your controller actions:
@authors = Author.find(:all)
render :json => @authors.to_json(:only => :name)
But of course you couldn’t, so I patched away by changing the to_json methods of Enumerable and Hash (and other types as well) to accept an optional options argument. Enumerables will pass on any options it receives to its elements. Hashes will respect :only and :except (as well as passing on the options to its elements).
Unambiguous (non-US-centric) dates and times
While Rails 1.2.3 (and 1.2.4) never supported encoding of Dates, Times and DateTimes, edge Rails has been happily supporting Date, Time and DateTime conversions to JSON since revision 6673. Unfortunately, the date string format is in MM/DD/YYYY format:
Time.now.to_json
=> "\"09/21/2007 12:15:02 UTC\""
Geoff Buesing suggested that Rails should change this to the more unambiguous YYYY/MM/DD format. Finding the right date format is important not only for readability reasons, it’s also important that the date string is directly parsable by the many browser JavaScript implementations using the JavaScript new Date(dateString) function. There is no formal spec of how dates should be represented in JSON, but it’s most convenient that strings representing dates can be directly converted into JavaScript Date objects.
Testing in several browsers and on different platforms, albeit not extensively, we settled on the %Y/%m/%d %H:%M:%S %z (strftime) format (more details in the comments of the Trac ticket).
Now it is:
Time.now.to_json
=> "\"2007/09/21 12:15:02 +0800\""
Much better.
What’s left?
Documentation, for one thing. ActiveRecord::Base#to_json is still undocumented (docfix patch). The to_json methods for Enumerable and Hash need documentation as well (will patch that soon).
ActiveRecord::Base#to_json also doesn’t deal with binary attributes, which can be easily resolved by Base64-encoding them (patch coming soon, it gets slightly complicated when trying to do a from_json). And of course, optimization improvements are always nice (decoding from JSON especially).
So, if you use JSON at all, please come in and help patch the remaining bits before Rails 2.0 rolls out. If you can’t (or more realistically, don’t have the time to) patch Rails yourself, do help out by verifying patches :).
October 3rd, 2007
Got an email not too long ago from Working With Rails (my profile) entitled “WWR September Hackfest Winner - Congrats!”, and almost deleted it thinking it was spam. I read it in the end (after all, how often do you see spam with “Rails” in the subject title), and turns out that my recent patches to Rails pushed me up to 6th position in the September Rails contributors rankings.
I vaguely remember seeing Rails Hackfest mentioned somewhere but only just realized it’s a “contest” run monthly. The winners are the top 10 contributors to Rails (contribution being determined by the number of accepted patches, docfixes, and even comments). That’s really nice of the sponsors and Working With Rails, since that wasn’t really what I’d expected in return for contributing to an Open Source project (that would be a sense of satisfaction, personally-speaking).
I’m just really glad that the JSON patches went into Rails before Rails 2.0 and it is satisfying to see my code get into Rails (I’ll blog about the patches in a separate post). There’s still some more work needed though - please help to verify and give suggestions or +1s ;).