# Custom associations

**URL:** <https://www.ruby-forum.com/t/custom-associations/174115>\
**Category:** Rails\
**Created:** [August 21, 2009, 1:16am UTC](https://www.ruby-forum.com/t/custom-associations/174115 "2009-08-21T01:16:00Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![paerez](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/5fc32e/32.png) [@paerez](https://www.ruby-forum.com/u/paerez)\
**Post date:** [August 21, 2009, 1:16am UTC](https://www.ruby-forum.com/t/custom-associations/174115/1 "2009-08-21T01:16:00Z")

</div>

Hi, I was wondering if somebody has any pointer for me.  
Here is what I have and trying to do.

Let’s say I have 2 models

WorkOrder ( id, ref\_number, desc) ( and a bunch of other fields)

OldRma ( id, ref\_number, customer\_data)

Work order is a big table that has all the info about the work order,  
Old rma contains older data, that is still imported from customer that  
needs to be referenced. Both models hav id as a primary field that can’t  
be changed ( so I can’t make ref\_number a primary key in either table)

ref\_number field is unique for OldRma, and there might be multiple  
WorkOrders with the same ref\_number.

I need to be able to reference both tables and run find statements with  
includes.

At first I wanted to change primary key on OldRma, but that is not an  
option as that field id is already used in other models.

I was able to add to WorkOrder

class WorkOrder \< ActiveRecord::Base

def oldrma  
OldRma.find\_by\_ref\_number(seld.ref\_number)  
end

end

So I can do:

w = WorkOrder.find\_by\_ref\_number(5)  
w.oldrma

Which kind of lets me have shortcuts for finding data.  
But what I need to do is

w = WorkOrder.find(:all, :conditions =\> “work\_orders.ref\_number = 1234”,  
:include = \> :oldrma )

This obviously breaks cause there is no direct association between two  
models.  
belongs\_to with a foreign\_key - won’t work cause I can’t change the  
primary keys on models. Rails doesn’t support secondary keys. So can  
somebody suggest a way to do it?

Any ideas?

---

<div class="post-metadata">

**Author:** ![paerez](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/5fc32e/32.png) [@paerez](https://www.ruby-forum.com/u/paerez)\
**Post date:** [August 21, 2009, 1:24am UTC](https://www.ruby-forum.com/t/custom-associations/174115/2 "2009-08-21T01:24:25Z")

</div>

On Aug 21, 12:16 am, nick ger [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
wrote:

> This obviously breaks cause there is no direct association between two  
> models.  
> belongs\_to with a foreign\_key - won’t work cause I can’t change the  
> primary keys on models. Rails doesn’t support secondary keys. So can  
> somebody suggest a way to do it?

both has\_many and belongs\_to take a :primary\_key option (which  
defaults to id). Is this what you are looking for?

Fred

---

<div class="post-metadata">

**Author:** ![paerez](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/5fc32e/32.png) [@paerez](https://www.ruby-forum.com/u/paerez)\
**Post date:** [August 21, 2009, 1:24am UTC](https://www.ruby-forum.com/t/custom-associations/174115/3 "2009-08-21T01:24:32Z")

</div>

Also to clarify why I need this. I could run a second statement in  
controller where I find the OldRma, but it’s slower then running an  
include, and OldRma - has other associations that need to be used, so an  
include would give me an option to have everything in one variable -  
which makes it easier to iterate through in a view, than trying to pull  
info from multiple variable, or doing w.oldrma every time I need  
something. Could easily get out of hand when you need to pull 100’s of  
records and display them. ( pagination is not an option. don’t ask me  
why, I just can’t explain to client then nobody wants to scroll down  
100’s of rows but…)

---

<div class="post-metadata">

**Author:** ![paerez](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/5fc32e/32.png) [@paerez](https://www.ruby-forum.com/u/paerez)\
**Post date:** [August 21, 2009, 1:27am UTC](https://www.ruby-forum.com/t/custom-associations/174115/4 "2009-08-21T01:27:38Z")

</div>

Frederick C. wrote:

> On Aug 21, 12:16ï¿½am, nick ger [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
> wrote:
> 
> > This obviously breaks cause there is no direct association between two  
> > models.  
> > ï¿½belongs\_to with a foreign\_key - won’t work cause I can’t change the  
> > primary keys on models. Rails doesn’t support secondary keys. So can  
> > somebody suggest a way to do it?
> 
> both has\_many and belongs\_to take a :primary\_key option (which  
> defaults to id). Is this what you are looking for?
> 
> Fred

Thanks for a reply Fred. But is the opposite of what I’m looking for.  
🙂

I need to be able to leave primary\_key (:id) as they are on the table  
right now, but also create another association between tables using  
ref\_number field.

So Let’s say I want legacy app to be able to access table using :id  
field. And these two tables communicate to each other using association  
on :ref\_number field. I know it’s not the best of designs, but I have to  
deal with what I’ve got.

---

<div class="post-metadata">

**Author:** ![paerez](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/5fc32e/32.png) [@paerez](https://www.ruby-forum.com/u/paerez)\
**Post date:** [August 21, 2009, 1:41am UTC](https://www.ruby-forum.com/t/custom-associations/174115/5 "2009-08-21T01:41:59Z")

</div>

On Aug 21, 12:27 am, nick ger [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
wrote:

> > both has\_many and belongs\_to take a :primary\_key option (which

Isn’t that precisely what the primary\_key option does ?

if you do belongs\_to :other\_class, :foreign\_key =\> ‘ref\_number’

then activerecord will look for a row in that table whose primary key  
is equal to the object’s ref number. If you say :primary\_key =\>  
‘other\_column’ it will look for rows in that table where other\_column  
has that value (and similarly for has\_many) - these options don’t  
change the table structure, just what the association uses to refer to  
that table.

Fred

---

<div class="post-metadata">

**Author:** ![paerez](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/5fc32e/32.png) [@paerez](https://www.ruby-forum.com/u/paerez)\
**Post date:** [August 21, 2009, 2:05am UTC](https://www.ruby-forum.com/t/custom-associations/174115/6 "2009-08-21T02:05:51Z")

</div>

Also the reason your previous suggestion wouldn’t work, cause when you  
specify foreign\_key, rails assumes, that it’s a primary key in the table  
you are referencing. Which it is not. ref\_number field is just a varchar  
field , that while unique is not a primary key in the OldRma model, and  
can’t be change to be one.

---

<div class="post-metadata">

**Author:** ![paerez](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/5fc32e/32.png) [@paerez](https://www.ruby-forum.com/u/paerez)\
**Post date:** [August 21, 2009, 1:59am UTC](https://www.ruby-forum.com/t/custom-associations/174115/7 "2009-08-21T01:59:51Z")

</div>

Fred,  
Perhaps a diagram would explain it better:

[http://www.gorbikoff.com/stuff/rails.png](http://www.gorbikoff.com/stuff/rails.png)

the relationship I’m trying to recreate is in red.

You can see that I can’t change the primary keys as they are already  
used in other models. So I need to create a custom association here.

Nick

---

<div class="post-metadata">

**Author:** ![paerez](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/5fc32e/32.png) [@paerez](https://www.ruby-forum.com/u/paerez)\
**Post date:** [August 21, 2009, 2:19am UTC](https://www.ruby-forum.com/t/custom-associations/174115/8 "2009-08-21T02:19:03Z")

</div>

Also I don’t want to add oldrma\_id and work\_order\_id to tables - cause  
then I have an extra variable to keep track off.

And has\_many\_and\_belong\_to wouldn’t work, cause again I ref\_number is  
not a primary key on either table and it’s their for history reasons.

---

<div class="post-metadata">

**Author:** ![paerez](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/5fc32e/32.png) [@paerez](https://www.ruby-forum.com/u/paerez)\
**Post date:** [August 21, 2009, 9:26am UTC](https://www.ruby-forum.com/t/custom-associations/174115/9 "2009-08-21T09:26:10Z")

</div>

On Aug 21, 1:05 am, nick ger [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> Also the reason your previous suggestion wouldn’t work, cause when you  
> specify foreign\_key, rails assumes, that it’s a primary key in the table  
> you are referencing. Which it is not. ref\_number field is just a varchar  
> field , that while unique is not a primary key in the OldRma model, and  
> can’t be change to be one.

THat’s the whole point of the primary key option. It says, for this  
association only, link the foreign key up to this column instead of  
linking it up to the table’s primary key. It doesn’t change the  
table’s primary key and it doesn’t affect any other relationships. It  
doesn’t matter if the other column isn’t the table’s primary key  
(after all if it were you wouldn’t need this option at all).  
Seriously, try it.

Fred
