www.flickr.com
Michael Kovacs' photos More of Michael Kovacs' photos
Recommend Me Cable Car Software logo

Sunday, June 18, 2006

Rails realities part 13 (STI and has_and_belongs_to_many don't get along)

Yesterday while trying to model some domain objects that need to be involved in a many-many relationship I ran into a problem where AR doesn't work with model objects that are using single table inheritance. How about an example of just what I'm talking about...
(These aren't the real domain model objects so don't pan me for bad design.)

def Band < ActiveRecord::Base
has_and_belongs_to_many :fans
end

def RedHotChiliPeppers < Band
end

def Fan < ActiveRecord::Base
has_and_belongs_to_many :bands
end

OK so that's the class structure let's fire up the console and create some objects:

>> fan = Fan.new
>> band = RedHotChiliPeppers.new
>> fan.bands
=> []
>> fan.bands<< band
ActiveRecord::AssociationTypeMismatch: Band expected, got RedHotChiliPeppers
from /usr/local/ror/lib/ruby/gems/1.8/gems/activerecord-1.14.1/lib/active_record/associations/association_proxy.rb:134:in `raise_on_type_mismatch'
from /usr/local/ror/lib/ruby/gems/1.8/gems/activerecord-1.14.1/lib/active_record/associations/association_collection.rb:24:in `<<'
from /usr/local/ror/lib/ruby/gems/1.8/gems/activerecord-1.14.1/lib/active_record/associations/association_collection.rb:23:in `<<'
from /usr/local/ror/lib/ruby/gems/1.8/gems/activerecord-1.14.1/lib/active_record/connection_adapters/abstract/database_statements.rb:51:in `transaction'
from /usr/local/ror/lib/ruby/gems/1.8/gems/activerecord-1.14.1/lib/active_record/transactions.rb:91:in `transaction'
from /usr/local/ror/lib/ruby/gems/1.8/gems/activerecord-1.14.1/lib/active_record/transactions.rb:118:in `transaction'
from /usr/local/ror/lib/ruby/gems/1.8/gems/activerecord-1.14.1/lib/active_record/associations/association_collection.rb:22:in `<<'
from (irb):33

I've been told that there's a patch that's pending release to fix this problem but in the meantime I've worked around this by moving the HABTM relationship from Band into the RedHotChiliPeppers subclass. I only have one other subclass of Band in my model so it's not too terrible to deal with having that relationship in both of those subclasses but this AR bug should be fixed.

A search through the bug database didn't find this particular bug but others that are closely related:


http://dev.rubyonrails.org/search?q=has_and_belongs_to_many+inheritance&ticket=on&changeset=on


As a result I filed a ticket for this:
http://dev.rubyonrails.org/ticket/5425


I'm not on edge rails (I'm using 1.1.2) so maybe this is fixed by now, guess we'll see by the activity on the ticket.


Friday, June 09, 2006

Page Up/Page Down and moving the caret in Textmate

For rails development TextMate has been the editor of choice for anyone using a mac because of the numerous features it has built in for rails. My #1 complaint with the editor has been the page up/page down behavior, namely the caret would never move when you performed a page up or down. I've been living with this deficiency for awhile now but decided to figure out how to fix this problem.

If you checkout the TextMate docs in section 16.3 "Text Move / Edit Actions", you'll see:


The master set of keys can be augmented by ~/Library/‍KeyBindings/‍DefaultKeyBinding.dict. The most common request with respect to key bindings is to have page up/down move the caret, and have home/end go to the beginning and end of the line. This article shows how this can be done.


You then arrive and discover that the article makes mention of the common request made to have the caret move with a page up/down and then immediately discusses that the article will provide an example for windows switchers where the home/end keys move to the beginning/end of the line respectively. Luckily if you read the article closely enough you'll see that he also provides an example for page up/down.


Turns out that the default key bindings in OSX do not move the caret on a page up/down. So the quick fix is to make sure that you create a blank file (unless you have already created a key binding file, then skip this step and just add the bindings below) called: ~/Library/KeyBindings/DefaultKeyBinding.dict

Then simply add:



{
/* page up/down */
"\UF72C" = "pageUp:";
"\UF72D" = "pageDown:";
}


to that file. Save it. Restart TextMate and voila! when you page up/down the caret will move with the scrolling activity.


This page is powered by Blogger. Isn't yours?