From: Peter Ertl Date: 2006-06-29T03:01:40+09:00 Subject: Re: How to model Hibernate multi-table inheritance with ActiveRecord? delegation is powerful, no question... > but if SomeAsset and AnotherAsset instances each hold a delegate Asset why not simply use inheritance? it's not that bad :-) class SomeAsset < Asset class AnotherAsset < Asset waaay tooo much java engineers here :-) -------- Original-Nachricht -------- Datum: Thu, 29 Jun 2006 02:17:24 +0900 Von: Jacob Fugal An: ruby-talk@ruby-lang.org Betreff: Re: How to model Hibernate multi-table inheritance with ActiveRecord? > On 6/28/06, Alex Young 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