# Modeling complex associations

**URL:** <https://www.ruby-forum.com/t/modeling-complex-associations/158099>\
**Category:** Rails\
**Created:** [January 19, 2009, 11:58am UTC](https://www.ruby-forum.com/t/modeling-complex-associations/158099 "2009-01-19T11:58:35Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![Till](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/22d042/32.png) [@Till](https://www.ruby-forum.com/u/Till)\
**Post date:** [January 19, 2009, 11:58am UTC](https://www.ruby-forum.com/t/modeling-complex-associations/158099/1 "2009-01-19T11:58:35Z")

</div>

Hi,

Is there any default way to model something like the following  
situation in ActiveRecord?:

A company has\_many :buildings which are associated to :company, e.g.  
in a polymorphic way.  
Moreover one and only one of the buildings is the company’s  
headquarter.

Thinking in terms of the database, I’d prefer to add an owning  
association, an thus have a has\_many :buildings plus a  
has\_one :headquarter, :class =\> “Building” assocation, where the  
foreign key “head\_quarter\_id” should be assigned to the company and  
refer to the buildings table.  
I’d prefer that to tagging one building with a headquarter-flag  
because there’s the advantage of only being forced to change one  
dataset (the company, more exactly its headquarter\_id), instead of  
changing two flags.

Is there any way to map that to ActiveRecord?

---

<div class="post-metadata">

**Author:** ![Till](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/22d042/32.png) [@Till](https://www.ruby-forum.com/u/Till)\
**Post date:** [January 19, 2009, 3:15pm UTC](https://www.ruby-forum.com/t/modeling-complex-associations/158099/2 "2009-01-19T15:15:57Z")

</div>

Thanks very much for the hint - I didn’t think of that problem.

> - you could create a polymorphic building with an interface for  
> headquarter and branch

I think it’s a good idea to differentiate headquarters and building  
using another model (did I get this right?)  
Would you suggest - assuming that building belongs\_to company in a  
polymorphic way - to create a table for headquarters? As it’s just a  
unique property among the set of buildings belonging to one company  
maybe it’s good to use STI and let Headquarter inherit from Building.  
In the database this would result in a kind of flag (the type column)  
as well, but maybe it would cause more readable code and prevent some  
“if building.headquarter” patterns.

---

<div class="post-metadata">

**Author:** ![Till](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/22d042/32.png) [@Till](https://www.ruby-forum.com/u/Till)\
**Post date:** [January 19, 2009, 1:18pm UTC](https://www.ruby-forum.com/t/modeling-complex-associations/158099/3 "2009-01-19T13:18:12Z")

</div>

be careful: you’re building a ring. that’s a complex and so trivial  
thing.

obvious problem: for a company to store the foreign key of its  
headquarter the building has to exist. for that building to store the  
foreign key of the company that it belongs to, the company has to  
exist.

to simplify it, there are a couple of solutions:

- you could just use an additional attribute in building  
“is\_headquarter” (bool) ← your mentioned headquarter flag
- you could add an additional model headquarter that has many  
branches, such that “a company has\_one headquarter” and “it has\_many  
branches through headquarter”. ← problem here: hard to upgrade a  
branch to headquarter and data-redundancy
- you could create a polymorphic building with an interface for  
headquarter and branch  
[http://wiki.rubyonrails.org/rails/pages/UnderstandingPolymorphicAssociations](http://wiki.rubyonrails.org/rails/pages/UnderstandingPolymorphicAssociations)

imho the last option seems to be the best.

---

<div class="post-metadata">

**Author:** ![Till](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/22d042/32.png) [@Till](https://www.ruby-forum.com/u/Till)\
**Post date:** [January 19, 2009, 4:11pm UTC](https://www.ruby-forum.com/t/modeling-complex-associations/158099/4 "2009-01-19T16:11:00Z")

</div>

I agree with Ar that you simply need a join table to hold the  
relationship from the Company to its Headquarters instead of using an  
object hierarchy and inheritance. Using Modules to insert and

class Company  
company\_id  
end

class Building  
building\_id  
end

class CompanyHeadquarters  
company\_id  
building\_id  
end

Having the CompanyHeadquarters object may come in handy if you need  
extra information about the Headquarters building that is different  
from a normal building.

On Jan 19, 9:44 am, Ar Chron [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> > I think it’s a good idea to differentiate headquarters and building  
> > using another model (did I get this right?)

---

<div class="post-metadata">

**Author:** ![Till](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/22d042/32.png) [@Till](https://www.ruby-forum.com/u/Till)\
**Post date:** [January 19, 2009, 3:44pm UTC](https://www.ruby-forum.com/t/modeling-complex-associations/158099/5 "2009-01-19T15:44:47Z")

</div>

> I think it’s a good idea to differentiate headquarters and building  
> using another model (did I get this right?)

That depends… is there something substantively different about a  
building that is designated as the headquarters? I.e., are you  
maintaining additional data that is specific to a “headquarters”?

If I think about bigger office buildings, there can be several companies  
that lease individual floors of a building (sometimes sections within  
floors). Any of those areas might be the individual company’s  
headquarters, while it’s all the same physical building.

So if companies can have space in multiple buildings, and a single  
building can house space for multiple companies, you need a join table  
that represents company-building combinations (officespaces?), and it  
seems that this join entity is what you would need to designate as a  
headquarters or not.

---

<div class="post-metadata">

**Author:** ![Till](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/22d042/32.png) [@Till](https://www.ruby-forum.com/u/Till)\
**Post date:** [January 19, 2009, 6:02pm UTC](https://www.ruby-forum.com/t/modeling-complex-associations/158099/6 "2009-01-19T18:02:05Z")

</div>

Ok, thanks!

Maybe it’s also easier to reflect the situation that a company moves  
its headquarter from one building to another. Then there’s only the  
join table which is affected.
