# Help with abstracting ActiveRecord models

**URL:** <https://www.ruby-forum.com/t/help-with-abstracting-activerecord-models/174383>\
**Category:** Rails\
**Created:** [August 26, 2009, 5:12am UTC](https://www.ruby-forum.com/t/help-with-abstracting-activerecord-models/174383 "2009-08-26T05:12:49Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![Jeff\_Larkin](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/7993a0/32.png) [@Jeff\_Larkin](https://www.ruby-forum.com/u/Jeff_Larkin)\
**Post date:** [August 26, 2009, 5:12am UTC](https://www.ruby-forum.com/t/help-with-abstracting-activerecord-models/174383/1 "2009-08-26T05:12:49Z")

</div>

Hi all. I’m looking for suggestions of how other people have  
implemented a situation like the following. I’d like to create a base  
activerecord model, let’s call it Widget, from which other classes are  
based. I’d like to store the name of the final class in the database  
and either use that information to load the proper class or to include  
a module that overrides certain methods of the base class. For  
example:

Widget \< AR: Base  
RSSWidget \< Widget  
HTMLWidget \< Widget

w = Widget.first

Currently w is a generic widget; it doesn’t know if it’s really a  
RSSWidget or an HTMLWidget. Really, what I’m more interest in is if  
something, say Page, has many widgets, then I can iterate through all  
widgets for an instance of page and each will cast itself to the  
appropriate subclass (or include the proper module).

Is there an AR hook that I can use immediately after the model is  
loaded from the database to include the necessary module and either  
deserialize any additional information or load additional properties  
from other tables? I’ve read that AR has an abstract\_class property,  
but it almost looks like it sees this problem from the other  
direction, with the tables belonging to the inherited classes, but  
maybe I’ve misunderstood it.

Any suggestions of how this may be done would be greatly appreciated.

Thanks,  
-Jeff

---

<div class="post-metadata">

**Author:** ![Jeff\_Larkin](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/7993a0/32.png) [@Jeff\_Larkin](https://www.ruby-forum.com/u/Jeff_Larkin)\
**Post date:** [August 26, 2009, 5:23am UTC](https://www.ruby-forum.com/t/help-with-abstracting-activerecord-models/174383/2 "2009-08-26T05:23:57Z")

</div>

On Tue, Aug 25, 2009 at 10:11 PM, Jeff Larkin[removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
wrote:

> RSSWidget \< Widget  
> Is there an AR hook that I can use immediately after the model is  
> loaded from the database to include the necessary module and either  
> deserialize any additional information or load additional properties  
> from other tables? I’ve read that AR has an abstract\_class property,  
> but it almost looks like it sees this problem from the other  
> direction, with the tables belonging to the inherited classes, but  
> maybe I’ve misunderstood it.
> 
> Any suggestions of how this may be done would be greatly appreciated.

It seems to me you’re thinking in Java or C++. Ruby isn’t about what  
type or class an object is based on so much as what the object can do.  
I don’t see very much object casting when I read other people’s Ruby.  
Mostly it’s just the primitives, string to ints,  
etc.

Google “ruby duck typing”, and check out respond\_to? and module mixins.

–  
Greg D.  
[http://destiney.com/](http://destiney.com/)

---

<div class="post-metadata">

**Author:** ![Jeff\_Larkin](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/7993a0/32.png) [@Jeff\_Larkin](https://www.ruby-forum.com/u/Jeff_Larkin)\
**Post date:** [August 26, 2009, 6:30am UTC](https://www.ruby-forum.com/t/help-with-abstracting-activerecord-models/174383/3 "2009-08-26T06:30:41Z")

</div>

On Aug 25, 2009, at 8:11 PM, Jeff Larkin wrote:

> RSSWidget \< Widget  
> Is there an AR hook that I can use immediately after the model is  
> -Jeff  
> Look up single table inheritance. It, by definition and  
> implementation, stores the name of the class in a database field. The  
> syntax for declaration is simply inheritance, so nothing special  
> there. The only requirement is that all database fields for the  
> subclasses be present in the table for the base class. Best of all,  
> when you do:

w = RSSWidget.first

w.class == RSSWidget  
=\> true

Does that meet the criteria you’ve spelled out? Because if it does,  
it’s been in Rails since before 1.0.

---

<div class="post-metadata">

**Author:** ![Jeff\_Larkin](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/7993a0/32.png) [@Jeff\_Larkin](https://www.ruby-forum.com/u/Jeff_Larkin)\
**Post date:** [August 26, 2009, 4:37pm UTC](https://www.ruby-forum.com/t/help-with-abstracting-activerecord-models/174383/4 "2009-08-26T16:37:42Z")

</div>

On Wed, Aug 26, 2009 at 12:29 AM, s.ross[removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> Does that meet the criteria you’ve spelled out? Because if it does, it’s  
> been in Rails since before 1.0.

And if it doesn’t meet his criteria, when if ever did STI get into  
Rails?

–  
Rick DeNatale

Blog: [http://talklikeaduck.denhaven2.com/](http://talklikeaduck.denhaven2.com/)  
Twitter: [http://twitter.com/RickDeNatale](http://twitter.com/RickDeNatale)  
WWR: [http://www.workingwithrails.com/person/9021-rick-denatale](http://www.workingwithrails.com/person/9021-rick-denatale)  
LinkedIn: [http://www.linkedin.com/in/rickdenatale](http://www.linkedin.com/in/rickdenatale)

---

<div class="post-metadata">

**Author:** ![Jeff\_Larkin](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/7993a0/32.png) [@Jeff\_Larkin](https://www.ruby-forum.com/u/Jeff_Larkin)\
**Post date:** [August 27, 2009, 12:33am UTC](https://www.ruby-forum.com/t/help-with-abstracting-activerecord-models/174383/5 "2009-08-27T00:33:52Z")

</div>

On Aug 26, 2009, at 6:47 AM, Rick DeNatale wrote:

> Rick DeNatale  
> if rails.include? STI  
> puts “sigh of relief – must be before today”  
> else  
> puts “pain of embarrassment – must be wrong”  
> end

# or…

if requirements =~ /STI/  
puts “STI must have been included in Rails before 1.0”  
else  
puts “STI implementation date not computable from given information”  
end
