February 27th, 2008
It’s been a slow week on the Rails trunk this week in terms of exciting changes.
This week’s report covers changes from 18 Feb 2008 to 24 Feb 2008 (the day the corresponding Rails Envy podcast was recorded).
ActiveResource::Base now accepts user and password configuration
You can now set the user and password for HTTP authentication in your ActiveResource models:
class Person < ActiveResource::Base
self.site = 'http://example.com/'
self.user = 'konata'
self.password = 'password'
end
This is a better way to specify authentication credentials than the current way of doing it by putting it all in the site (e.g. self.site = 'http://konata:password@example.com/').
Related changeset: http://dev.rubyonrails.org/changeset/8891
script/plugin install now supports SVN export
You can now pass the -e/--export option to script/plugin install to do an Subversion export of the plugin. This allows you to then check in the plugin’s files into your own repository. Though seriously, if anyone really wants to do this, I’d suggest they use Piston. That is, for those of us still using Subversion rather than Git.
Related changeset: http://dev.rubyonrails.org/changeset/8921
Bug fixes for associations preloading
There’ve been some bug fixes the associations preloading change mentioned in Living on the edge #5:
- http://dev.rubyonrails.org/changeset/8894 - Fixed a bug where associations that were preloaded (using nested
:includes) errors out when the associations return nil (i.e. when there are no associated records).
- http://dev.rubyonrails.org/ticket/11154 - Fixed a bug where nested includes were assuming that all records are from the same class. This is not true for polymorphic associations, causing problems when they were being used.
Yup, that’s it for this week. As usual, let me know of anything I might have missed or any suggestions you may have in the comments!
February 26th, 2008
Subscribers who read my blog for Ruby- or Mozilla-related posts should ignore this post, it’s another of those blogging as catharsis posts. To my defence, I haven’t done one of those for a really long time!
If you’re staying in Singapore and looking to try out the food at Shokudo Japanese Food Bazaar after it was featured in the local newspaper, my advice to you is, “don’t bother!” Why? In 2 words, horrible service.
Despite some positive reviews (yes, the decor is not too bad), my dining experience at Shokudo consisted mostly of getting the service crew’s attention (and failing spectacularly despite standing right at the counter) and being scowled at or avoided by most of the staff (which is not good, since being a bazaar-style restaurant, you needed to place your order at each stall manned by different members of the service crew).
My friends and I were speculating that either the staff got scolded that day (and reacted negatively to that), or they were just too stuck up because business was good. Either way, it was just terrible. When leaving, I even got rudely reminded that I’d left that one of those things they gave you to reserve a table. Did I mention the service was horrible? (Granted, there were 2 counters where the staff were attentive and actually quite friendly - this was at the macha drink stall and the katsu curry counter.)
What about the food? With such bad service I would say no one shouldn’t really care about the quality of the food - thankfully enough, the food is of a consistently mediocre level to even bother!
Has anyone had a similar experience at Shokudo, or was it just our unlucky day?
February 19th, 2008
Here’s this week’s update of the important changes that have been happening on edge Rails. There were lots of performance patches this week, credit mostly due to the guys from Acunote and their latest blog post on optimizing Rails.
This week’s report covers changes from 11 Feb 2008 to 17 Feb 2008 (the day the corresponding Rails Envy podcast was recorded).
ActiveRecord::Base#attributes-related optimizations
The ActiveRecord::Base#attributes_before_typecast no longer clones attribute unnecessarily.
Related changeset: http://dev.rubyonrails.org/changeset/8858
ActiveRecord::Base#attributes now no longer supports options. The ActiveRecord::Base#attributes method used to support :only and :except options, which are actually unnecessary since it returns a Hash. You can use Hash#slice or Hash#except (both ActiveSupport core extensions) directly on the hash.
Related changeset: http://dev.rubyonrails.org/changeset/8863
ActiveRecord associations optimized by avoiding named block arguments
Alexander Dymo is at it again optimizing ActiveRecord performance, this time by avoiding passing named block arguments. Turns out that it is faster and more memory efficient in Ruby to pass blocks like this:
def foo
bar { |*block_args| yield(*block_args) if block_given?
end
instead of passing the block around like so:
def foo(&&block)
bar(&block)
end
Occurrences of the more expensive way of passing blocks have been replaced in the ActiveRecord associations code so associations are lighter to use.
For a more detailed write-up, check out Alexander’s blog entry.
Related changeset: http://dev.rubyonrails.org/changeset/8865
ActiveRecord associations optimized by using symbol callbacks instead of string callbacks
Again from Alexander Dymo, this patch also improving ActiveRecord association performance. Internally, ActiveRecord associations code uses a lot of string callbacks (e.g. before_save "some_ruby_code_to_eval"). It turns out that that is significantly more expensive compared to simply using Module#define_method because when the callback string is evaluated, the binding needs to be passed along. Passing the binding takes up memory (which is bad, of course).
The internal associations code has been changed to use that define_method now, and if you’re using a lot of associations, you would save megabytes of memory! (Alexander’s blog post has more detailed benchmarks.)
Remember, when writing your own before and after filters, not to use a string that needs to be evaled!
Related changeset: http://dev.rubyonrails.org/changeset/8867
Improve ActiveRecord::Base#save performance by avoiding repeated calls to ActiveRecord::Base#connection
Another Alexander Dymo performance patch. This particular patch improves performance by getting the connection object just once and calling it directly, instead of needlessly calling several times. This should improve ActiveRecord::Base#save performance.
Related changeset: http://dev.rubyonrails.org/changeset/8871
ActiveRecord associations now support the :readonly option
ActiveRecord::Base#find supports the :readonly option to retrieve records that were read-only (i.e. you couldn’t save them). Now you can do the same for associations, like so:
has_many :comments, :readonly => true
This allows you to protect associated records from being saved.
Related changeset: http://dev.rubyonrails.org/changeset/8864
String#squish and String#squish! to remove consecutive chunks of whitespace
A String#squish extension has been added that trims whitespace from both ends of a string, and compressing consecutive whitespace groups within the string into 1 space each.
For example,
@description = %{ String#squish() allows me to write long strings
inside my Ruby code, without having to worry about indentation,
the page margin, spaces, tabs or newlines. "double" or 'single'
quotes are both fine, and #{interpolation} works. }.squish
Related changeset: http://dev.rubyonrails.org/changeset/8878
As always, let me know of any inaccuracies or any suggestions you may have in the comments, see you guys next week!
February 13th, 2008
It’s that time of the week again (every Wednesday for the overly observant, coinciding with the release of the Rails Envy podcast) for some choice updates of what changes have been happening on edge Rails. This week’s report covers changes from 4 Feb 2008 to 10 Feb 2008 (the day the Rails Envy podcast was recorded).
More efficent ActiveRecord::Base#attributes
ActiveRecord::Base#attributes returns a hash of all attributes with clones of their objects as values. This unnecessary cloning is expensive, and has now been removed. ActiveRecord::Base#attributes now returns a hash of values of the attributes.
Thanks to Juanjo Bazan, there have been 2 further patches (after the podcast was recorded) related ActiveRecord::Base#attributes that further improves ActiveRecord’s performance: removal of cloning from ActiveRecord::Base#attributes_before_typecast, and removing options (:only and :except options, specifically) from ActiveRecord::Base#attributes.
Related changeset: http://dev.rubyonrails.org/changeset/8824
ActiveResouce::Base#exists? now uses HTTP HEAD instead of a GET
A HTTP HEAD request is really all that is needed to check for existence (200 == exists, 404 == doesn’t exist). This has been changed to HEAD from a GET request, which is more efficient since all we retrieve are the HTTP headers and there’s no unnecessary instantiation of the ActiveResource object.
Related changeset: http://dev.rubyonrails.org/changeset/8827
Time zone support for ActiveRecord, and config.time_zone property for specifying a default Time Zone
ActiveRecord models now have time zone-aware attribute readers and writers. Times returned from ActiveRecord attribute readers now have a time_zone attribute themselves, allowing time zone-aware calculations.
You can now configure the default Time.zone value with config.time_zone in your environment.rb. Setting this will enable time zone-awareness for ActiveRecord models.
Related changeset: http://dev.rubyonrails.org/changeset/8806
A Template class has been introduced to ActionView
As part of the ActionPack refactoring that’s still ongoing, a ActionView::Template class has been introduced to encapsulate all the data relevant to the currently rendered template. This is largely an internal refactoring so Rails users shouldn’t be affected.
Related changeset: http://dev.rubyonrails.org/changeset/8805
Concrete sweeper classes
You can now use an explicit class when declaring a cache_sweeper. E.g.
class ListsController < ApplicationController
caches_action :index, :show, :public, :feed
cache_sweeper Sweepers::List, :only => [ :edit, :destroy, :share ]
end
Related changeset: http://dev.rubyonrails.org/changeset/8819
As always, let me know of any inaccuracies or any suggestions you may have in the comments - this week’s report is a little rushed because I’m a little late in posting it up!
February 6th, 2008
Here’s another week of noteworthy updates on the Rails trunk. Thanks once again to the Rails Envy podcast for featuring my updates, and even bigger thanks to the Rails contributors and committers who make things happen. This week’s Living on the Edge was covered in Rails Envy podcast #17.
The company I work for, Bezurk (yeah we know some of you hate the name “Bezurk” - that’s going to change), is currently looking for a Ruby developer to join our ranks. This person will be working mainly on Ruby-based web development projects. As we all know, “Rails doesn’t scale” (delivered in Jason Seifer-style - meaning it’s just a joke!) so we’d love anyone who’s up for a challenge and who’s also willing to work outside the Rails comfort zone (our current favorite: Ramaze). Our Ruby team currently comprises 3 experienced developers and 1 up and coming Rubyist.
We’re active Open Source contributors (Arun released ActiveCouch recently), while I am a Rails contributor (I’m ‘chuyeow’ on the Rails Trac) myself.
If all this sounds interesting enough to you, do check out the full job description and drop us an email. Yes, we’re serious when we said “+1 for DotA/Counterstrike skills)”. There’s a catch though - you have to work on location at our office in Singapore.
Anyway, let’s get back on topic - this weeks’ report covers changes from 28 Jan 2008 to 3 Feb 2008 (the day the Rails Envy podcast was recorded).
Saving, creating and updating ActiveRecord objects is more efficient
Thanks to Gleb Arshinov and Alexander Dymo with their blog post and patches about improving Rails performance by approaching it via minimizing garbage collection, saving, creating, and updating ActiveRecord objects is now significantly more efficient.
The expensive ActiveRecord::Base#attributes method is no longer called internally, so there’s no unnecessary cloning of attribute values. Less memory usage means less garbage collection, which means better performance!
Related changeset: http://dev.rubyonrails.org/changeset/8770
SQL calls and rendering are faster
This patch is courtesy of Gleb Arshinov and Alexander Dymo too.
Rails surrounds every SQL call and ActionView::Base#render with the ruby method Benchmark#realtime so that it can print out some benchmarking numbers. Benchmark#realtime allocates an unnecessary 45k of memory per call (who knew!). This has been monkey patched in Rails to a leaner implementation, reducing memory usage and increasing performance.
Related changeset: http://dev.rubyonrails.org/changeset/8771
MySQL adapter slight optimization
Table and column names in the MySQL adapter are now cached in instance variables, reducing memory allocations (and thus the need for GC).
Related changeset: http://dev.rubyonrails.org/changeset/8794
script/generate does Git!
script/generate now allows you to pass the ‘–git’ (or ‘-g’) option to add the generated files to git (much like how you could do the same with Subversion with ‘-c’ or ‘–svn’). This patch is the work of Steven Soroka so nice work Steven!
Related changeset: http://dev.rubyonrails.org/changeset/8772
map.resources :products, :as => ’something_else’
Here’s something that will make non-english Rails developers happy: you can now do, for example,
map.resources :comments, :as => 'comentarios'
so that you can keep having your model names independent of what URLs you’d actually like to appear on the site.
The above map.resources means that you can keep your resource and model names in English (Comment), while having URLs like this: /comentarios/123.
Related changeset: http://dev.rubyonrails.org/changeset/8785
:index option for form_for and fields_for to simplify multi-model forms
Inspired by a Railscasts episode where Ryan Bates mentions how ugly it is to have to pass :index => nil to prevent #text_field (and other form helpers) from inserting the model’s ID in the input name (e.g. project[task_attributes][123][name] when what you really want is project[task_attributes][][name]).
Meaning instead of
<% fields_for "project[task_attributes][]", task do |f| %>
<%= f.text_field :name, :index => nil %>
<%= f.hidden_field :id, :index => nil %>
<% end %>
you can now do:
<% fields_for "project[task_attributes][]", task, :index => nil do |f| %>
<%= f.text_field :name %>
<%= f.hidden_field :id %>
<% end %>
Related changeset: http://dev.rubyonrails.org/changeset/8786
No more emails in your production logs
You’d probably have noticed that ActionMailer logs entire email messages in the log, even in production. Well, it’s been changed to be less verbose now. At the :info log level, only the recipients are logged. You can still see the entire email at the :debug log level (which is the default for development environment).
Related changeset: http://dev.rubyonrails.org/changeset/8781
As always, let me know of any inaccuracies or any suggestions you may have in the comments. Oh, and if you liked this, do me a favor by submitting it to Ruby Reddit.