On 6/28/06, Alex Young <alex / blackkettle.org> wrote: > I'd have SomeAsset and AnotherAsset instances each hold a delegate Asset > object that they proxy any calls they can't answer themselves to. I've > played around a little with trying to implement a full class table > inheritance scheme for AR on that basis, but never really had enough > need for it myself to polish it up. I agree with Alex here. While inheritance was what the tables were originally trying to emulate, composition was the resulting design anyways. With Ruby and it's duck typing, inheritance isn't required for the ability to pass a SomeAsset where an Asset is expected. Java's static typing would require SomeAsset to "be a" Asset, but Ruby only needs SomeAsset to "quack like" an asset, which can be covered with judicious use of composition and method_missing. I'd actually provide a mixin that sets up this method_missing. Example: class Asset < ActiveRecord::Base # we're leaving out the reverse relationship to the "child" classes # -- just as a parent class implementation wouldn't really know about # the classes descended from it def xyzzy # model specific functionality end def hidden # model specific functionality that's not delegatable end module Delegator AssetDelegates = [ :prop1, :prop1=, :xyzzy ] def self.included(other) other.module_eval <<-END # we use belongs_to rather than has_one because the foreign key # is in this table belongs_to :asset alias :__asset_delegator_old_mm :method_missing def method_missing(method, *args, &block) if AssetDelegates.include?(method) self.asset.send(method, *args, &block) else __asset_delegator_old_mm(method, *args, &block) end end END end end end class SomeAsset < ActiveRecord::Base include Asset::Delegator def xyzzy # override Asset's implementation of xyzzy, feels just like # inheritance, except that if we want to call up to the "parent" # version, we need to use asset.xyzzy rather than super end end class AnotherAsset < ActiveRecord::Base include Asset::Delegator # make the hidden method, which wasn't explicitly delegated, available # from this "subclass" def hidden asset.hidden end end Jacob Fugal