# Inheritance in Rails - I need some help

**URL:** <https://www.ruby-forum.com/t/inheritance-in-rails-i-need-some-help/93946>\
**Category:** Rails\
**Created:** [April 15, 2006, 10:07pm UTC](https://www.ruby-forum.com/t/inheritance-in-rails-i-need-some-help/93946 "2006-04-15T22:07:10Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![adambeazley](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/5f9b8f/32.png) [@adambeazley](https://www.ruby-forum.com/u/adambeazley)\
**Post date:** [April 15, 2006, 10:07pm UTC](https://www.ruby-forum.com/t/inheritance-in-rails-i-need-some-help/93946/1 "2006-04-15T22:07:10Z")

</div>

I’ve got a model, “category” and another model “subcategory.” Each  
subcategory belongs\_to a category, and a category has\_many  
subcategories.

What I need to do is set it up so that I can search Category and  
Subcategory with one .find call. So:

Category.find(:all, \<etc)

will find categories and subcategories.

Now, I believe this can be done by making Subcategory a subclass of  
Category. Am I right? Unfortunately, there’s almost nothing in AWD about  
subclasses and has\_many relationships, so I’m lost. I tried to just  
change Subcategory to extend Category in the model, but that led to  
errors (no such field: “categories.category\_id”). What else do I need to  
change to allow Subcategory to extend Category and also belong\_to a  
category?

Thanks,

Adam

---

<div class="post-metadata">

**Author:** ![adambeazley](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/5f9b8f/32.png) [@adambeazley](https://www.ruby-forum.com/u/adambeazley)\
**Post date:** [April 15, 2006, 10:49pm UTC](https://www.ruby-forum.com/t/inheritance-in-rails-i-need-some-help/93946/2 "2006-04-15T22:49:00Z")

</div>

Adam,

I would probably do this with a single table that references itself,  
rather than have a new model Subcategory extend from Category.  
Basically you just need a categories table that contains a parent\_id  
column referring to another row in that same table. There is a brief  
discussion of this at:

[http://wiki.rubyonrails.com/rails/pages/HowToCreateASelfReferentialHasManyRelationship](http://wiki.rubyonrails.com/rails/pages/HowToCreateASelfReferentialHasManyRelationship)

It is also discussed in AWD ( ~ page 255 ) when they go over “Acts As  
Tree”.

Hope that helps,

Jeff

---

<div class="post-metadata">

**Author:** ![adambeazley](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/5f9b8f/32.png) [@adambeazley](https://www.ruby-forum.com/u/adambeazley)\
**Post date:** [April 15, 2006, 10:49pm UTC](https://www.ruby-forum.com/t/inheritance-in-rails-i-need-some-help/93946/3 "2006-04-15T22:49:06Z")

</div>

On Sat, Apr 15, 2006 at 10:07:10PM +0200, Adam B. wrote:

> Now, I believe this can be done by making Subcategory a subclass of  
> Category. Am I right?

Possibly-sorta, if when you say “subclass” you mean to use single-table  
inheritance. In that instance, yes, you can search Categories and also  
get  
matching subcategories, because STI is wonderfully intelligent about  
that  
sort of thing, like so:

CREATE TABLE categories (  
id INTEGER PRIMARY KEY,  
type VARCHAR(255) NOT NULL,  
name VARCHAR(255) NOT NULL,  
category\_id INTEGER  
);

class Category \<\< ActiveRecord::Base  
has\_many :subcategories  
end

class SubCategory \<\< Category  
belongs\_to :category  
end

(All that off the top of my head, so it might not be strictly correct)

Then, when you do a Category.find(), the SQL that will be generated will  
include “WHERE type=‘Category’ OR type=‘SubCategory’”, while  
SubCategory.find() will only have “WHERE type=‘SubCategory’”.

Speaking structurally, though, I’m not sure that STI really describes  
what  
you’re looking for. I’d consider putting together my own  
Category.find()  
type method that also ran the find on the subcategories itself, or else  
using something like acts\_as\_tree to do the whole thing (although I  
don’t  
know if acts\_as\_tree has the searching capabilities you want – I’ve  
never  
used it myself).

- Matt

---

<div class="post-metadata">

**Author:** ![adambeazley](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/5f9b8f/32.png) [@adambeazley](https://www.ruby-forum.com/u/adambeazley)\
**Post date:** [April 16, 2006, 12:45am UTC](https://www.ruby-forum.com/t/inheritance-in-rails-i-need-some-help/93946/4 "2006-04-16T00:45:26Z")

</div>

Adam  
\> What I need to do is set it up so that I can search Category and  
\> Subcategory with one .find call. So:  
\> Category.find(:all, \<etc)  
\> will find categories and subcategories.

You could aggregate 2 searches in 1 call :

(untested:)

def find\_deep (\*args)  
result = Category.find(args)  
result \<\< Subcategory.find(args)  
result.flatten  
end

Alain

---

<div class="post-metadata">

**Author:** ![adambeazley](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/5f9b8f/32.png) [@adambeazley](https://www.ruby-forum.com/u/adambeazley)\
**Post date:** [April 15, 2006, 11:50pm UTC](https://www.ruby-forum.com/t/inheritance-in-rails-i-need-some-help/93946/5 "2006-04-15T23:50:24Z")

</div>

Thanks guys!

-Adam

---

<div class="post-metadata">

**Author:** ![adambeazley](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/5f9b8f/32.png) [@adambeazley](https://www.ruby-forum.com/u/adambeazley)\
**Post date:** [April 16, 2006, 1:26am UTC](https://www.ruby-forum.com/t/inheritance-in-rails-i-need-some-help/93946/6 "2006-04-16T01:26:36Z")

</div>

Hmmm. I have a different but related question. Is there such a thing as  
an “includes” condition for .find? i.e. if I’m searching for listings  
(which habtm categories) that are in a certain category with id =  
category\_id I could do:

Listing.find(:all, :conditions =\> [ “categories INCLUDE ?”, category\_id  
]

and, as an extension, is there any way to find a listing that is in a  
category with category\_id = one of [id1, id2, id3]. That way I could  
do something like:

Listing.find(:all, :conditions =\> ["name = ?, or ,  
or ",  
“%#{params[:search\_string]}%”,  
\<category\_ids\>, \<subcategory\_ids\>]

and find every listing with one search.

It seems like it’d be something I could do with a pure-Ruby .find, but  
I’m not sure how hard that would be to integrate.

-Adam

---

<div class="post-metadata">

**Author:** ![adambeazley](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/5f9b8f/32.png) [@adambeazley](https://www.ruby-forum.com/u/adambeazley)\
**Post date:** [April 16, 2006, 1:28am UTC](https://www.ruby-forum.com/t/inheritance-in-rails-i-need-some-help/93946/7 "2006-04-16T01:28:05Z")

</div>

Formatting on that last pseudo-code chunk got really messed up.

Listing.find(:all, :conditions =\>  
["name = ?,  
or ,  
or ",  
“%#{params[:search\_string]}%”, \<category\_ids\>, \<subcategory\_ids\>]

---

<div class="post-metadata">

**Author:** ![adambeazley](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/5f9b8f/32.png) [@adambeazley](https://www.ruby-forum.com/u/adambeazley)\
**Post date:** [April 16, 2006, 9:41am UTC](https://www.ruby-forum.com/t/inheritance-in-rails-i-need-some-help/93946/8 "2006-04-16T09:41:45Z")

</div>

Adam  
\> Formatting on that last pseudo-code chunk got really messed up.  
\> Listing.find(:all, :conditions =\> ["name = ?,  
\> or ",  
\> “%#{params[:search\_string]}%”, \<category\_ids\>, \<subcategory\_ids\>]

When in doubt, just do it… with the console:

```
./script/console
>> Foo.find_by_sql('select * from foes where id in (1,2,3,4,5)')

```

(On Windows, you launch the console with  
ruby script\console  
)

Alain

---

<div class="post-metadata">

**Author:** ![adambeazley](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/5f9b8f/32.png) [@adambeazley](https://www.ruby-forum.com/u/adambeazley)\
**Post date:** [April 16, 2006, 9:09pm UTC](https://www.ruby-forum.com/t/inheritance-in-rails-i-need-some-help/93946/9 "2006-04-16T21:09:33Z")

</div>

Thanks. I did end up solving the problem with a few extra steps, but  
I’ll remember that SQL query in the future. 🙂

-Adam
