# Complex associations

**URL:** <https://www.ruby-forum.com/t/complex-associations/192641>\
**Category:** Ruby\
**Created:** [August 3, 2010, 3:56pm UTC](https://www.ruby-forum.com/t/complex-associations/192641 "2010-08-03T15:56:42Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![Trish](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/919ad9/32.png) [@Trish](https://www.ruby-forum.com/u/Trish)\
**Post date:** [August 3, 2010, 3:56pm UTC](https://www.ruby-forum.com/t/complex-associations/192641/1 "2010-08-03T15:56:42Z")

</div>

I am working on a project that has some complex table associations,  
and I am having a hard time declaring this association in a Model, and  
fear it can’t be done.

Here is an example of my issue…

class StoreType \< ActiveRecord::Base; end  
class Store \< ActiveRecord::Base; end  
class Department \< ActiveRecord::Base; end  
class Product \< ActiveRecord::Base; end

A StoreType has many stores and a Store has many Department. However,  
both Store and Department have many products. An product has the  
columns store\_id and department\_id which are mutually exclusive. This  
is because a Product may belong directly to a Department, or it may be  
a ‘global’ product that belongs directly to the Store.

What I’d like to do is have an association in the StoreType model that  
would give me all products for that StoreType.

Currently, I have set up the following associtations on StoreType:

class StoreType \< ActiveRecord::Base  
has\_many :stores  
has\_many :departments, :through=\>:stores

has\_many :store\_products, :through=\>:stores, :source=\>:products, :uniq  
=\> true

has\_many :department\_products, :through=\>:departments,  
:source=\>:products, :uniq  
=\> true  
end

This is using the Nested Has Many Through plugin to achieve the nested  
association (department\_products).

However, I’d like to have a generic ‘products’ association for  
StoreType that pulls a combination of the two product associations.  
I’d like to do this through an association instead of just through a  
function because I want to gain the dynamic methods created by  
has\_many, specifically the “collection.find(…)” method so I can add  
more conditions to the collection.

Is there a way to do this?

Thanks in advance!  
Trish

---

<div class="post-metadata">

**Author:** ![Trish](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/919ad9/32.png) [@Trish](https://www.ruby-forum.com/u/Trish)\
**Post date:** [August 3, 2010, 4:58pm UTC](https://www.ruby-forum.com/t/complex-associations/192641/2 "2010-08-03T16:58:35Z")

</div>

Trish wrote:

> Is there a way to do this?

Named or anonymous scopes perhaps. See these posts:  
[http://blog.ethanvizitei.com/2009/05/joins-and-namedscopes-in-activerecord.html](http://blog.ethanvizitei.com/2009/05/joins-and-namedscopes-in-activerecord.html)

> **[Anonymous scope, the unknown cousin of Named scope](http://webjazz.blogspot.com/2008/06/anonymous-scope-unknown-cousin-of-named.html)**
>
> Last time, I showed you the well known named scopes . This time, I'll talk about the little documented anonymous scopes. Anonymous scopes w...

So I’m guessing something like this (completely untested):

class Store  
def products  
Product.scoped(:joins =\> :department,  
:conditions=\>[“products.store\_id=? or (products.department\_id =  
departments.id and departments.store\_id=?)”, id, id])  
end  
end

And the reverse:

class Product  
def store  
if store\_id  
Store.find(store\_id)  
elsif department\_id  
Store.find\_first(:joins =\> :department,  
:conditions=\>[“stores.id = departments.store\_id and  
departments.id = ?”, department\_id])  
end  
end  
end

I’m not quite sure I’ve understood the model though. A particular  
product can only be sold in one department or one store? If another  
store wants to stock it as well, do you need another Product row?

---

<div class="post-metadata">

**Author:** ![Trish](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/919ad9/32.png) [@Trish](https://www.ruby-forum.com/u/Trish)\
**Post date:** [August 3, 2010, 6:23pm UTC](https://www.ruby-forum.com/t/complex-associations/192641/3 "2010-08-03T18:23:04Z")

</div>

Thanks for the input. I will give these a shot. Sorry about the  
example… it was just my way of trying to simplify what we have going  
on in our application. StoreType, Store, Department, and Product are  
just models I “invented” to get my problem across 🙂

After digging into this further, it appears that the _real_ issue I’m  
trying to solve is how to get the store\_products and  
department\_products in one SQL statement and be able to sort on an  
Store attribute (i.e. Store Name). This is for an existing project  
that used to do this with pure SQL, and had a lot of hard-coding for  
sort orders.

The end result is for a report that has multi-sortable columns that  
rely on MySQL ORDER BY to get the proper orders.

Also… sorry about the double post (to those who may have  
noticed 🙂 ) It did not appear that my original posted, so it’s not  
that I was being impatient, it’s that I was blind 🙂

Thanks!  
Trish
