ActiveRecord patches
Two patches to ActiveRecord (the database part of Ruby on Rails) have recently been made during development of NorfelloCMMS. Both patches are needed to make NorfelloCMMS function correctly.
Source code: http://cmms.norfello.com/cmms/file/trunk/config/active_record_patch.rb (contains both patches).
Abstract models and single table inheritance (ActiveRecord::Base)
First patch is to ActiveRecord::Base (Base for short). It makes model classes who are using single table inheritance and who have an abstract superclass behave corretly, i.e. as the model would if it were to descend directly from Base. The patch makes Base#descends_from_active_record? return true if and only if models base class (Base#base_class) is the model itself i.e. if the model descends directly from Base or if the model descends from an abstract model which descends directly or through other abstract models from Base. This prevents Base#add_conditions! from adding type conditions to models database queries when the model has an abstract superclass descending from Base. The patch might fix other problems too, ones that I haven't encountered.
I'll give a simple example what kind of problems appear without this patch. Suppose we have a class Sti using single table inheritance, who has subclasses X and Y. When we make a query Sti.find(:all) it executes SQL "SELECT * FROM stis" giving all objects of all classes saved to the "stis" table. Now suppose that Stis has an abstract superclass descending from Base, or maybe from another abstract class descending from Base for that matter. (Model can be abstract by setting class attribute abstract_class true.) Now the query Sti.find(:all) executes SQL "SELECT * FROM stis WHERE stis.type = 'Sti'" if Sti's subclasses (X and Y) are not loaded or SQL "SELECT * FROM stis WHERE stis.type = 'Sti' OR stis.type = 'X'" if X is loaded etc. So there are additional type conditions in these queries, which weren't present when Sti didn't descend from an abstract class. One would expect that a model descending from an abstract base class would behave exactly like a model descending from Base. So to make it so use this patch.
Binary data corruption on SQLite (ActiveRecord::ConnectionAdapters::SQLiteColumn)
The second patch fixes quoting of binary (blob) values on SQLite (which happens in the class ActiveRecord::ConnectionAdapters::SQLiteColumn). The problem conserns both SQLite 3 and older SQLite 2. Original implementation freguently caused data corruption. Although the original code looked fine, it often didn't quote all intended binary values and likewise dequoting requlary failed. The patch should do exactly what the original code was meant to do. We haven't encountered any corruption since this patch.