Tuesday, August 28, 2007

subqueries in rails




Sometimes Rails just drives me absolutely batty with it's "magic stuffing". I'm all for terse and beautiful syntax, but sometimes it just seems to be randomly put together, and almost impossible to Google for.

My latest in this was that I had a model that belongs_to another model, which in turn belongs_to another model. Something like this:



class GroceryBinItem < ActiveRecord::Base
belongs_to :bin
end

class Bin < ActiveRecord::Base
belongs_to :delivery_date
end

class DeliveryDate < ActiveRecord::Base
end



The DeliveryDate model contains a "date" field.

I wanted to find all the GroceryBinItems that were added after a certain date. Simple, yes? Well, I would have thought so as well, and in the end, it was some simple code that did it, but finding that information was practically impossible, and is not well documented.

Here's what I needed to do:


def self.added_to_bins_since_last_inventory(grocery_item_id)
inventory_update = InventoryUpdate.current
current = find(:all,
:conditions => [ "grocery_item_id = ? AND delivery_dates.date > ?" ,
grocery_item_id, inventory_update.date ],
:include => [{:bin => :delivery_date}]
)
end


The magic bit is the


:include => [{:bin => :delivery_date}]


And what this does is to do a normal :include LEFT JOIN, like you would go ":include [:bin]", but then also include the :delivery_date model as well.

Yes, that is a hash inside of an array.

Way too much magic. It should be more verbose and easier to actually search for. How many times am I going to need to do this? Probably not very much, and if I don't need to do it all the time, the amount of time that I spend searching for the right magic words is going to vastly outweigh the amount of time it takes to type something a bit longer and more verbose.

But then again, this is the whole problem with the Rails community, it's a little too DRY, and a little too magic.

And this concludes the rant for today. :)