Updating Collections

I got another patch included into Rails 0.13, more specifically into the ActiveRecord component. It helps at updating has-many and has-and-belongs-to-many (habtm) relationships, by implementing collection=(list) and collection_ids=(list) methods for these associations that will update the collection as expected. Here is an example:

class User
  has_and_belongs_to_many :groups
end
user = User.new
user.groups = [ Group.find(1), Group.find(2) ]
user.group_ids = [ "2", "3" ]

The methods are implemented in such a way, that they first compute the difference to the current state and then perform the update. This way, if you only remove or add one group with your assignment only 1 SQL statement will be executed.

As a further goodie, the complexity is only “O(n log n)” by using Ruby’s sets for bigger n. For smaller values of n (currently less than 100), Array#include? is used as it should have better constants than the red-black-trees used for sets. Take a look at the source if you are interested in the details. As always, Ruby is pretty succint.

The new collection_ids= method makes it easy to update has-many and habtm relationships via checkboxes or select fields without any extra support in the controller. Take a look at this wiki page for details.