# Denormalize DB by adding redundant foreign keys to tables

**URL:** <https://www.ruby-forum.com/t/denormalize-db-by-adding-redundant-foreign-keys-to-tables/164442>\
**Category:** Rails\
**Created:** [April 1, 2009, 2:45pm UTC](https://www.ruby-forum.com/t/denormalize-db-by-adding-redundant-foreign-keys-to-tables/164442 "2009-04-01T14:45:02Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![fipa](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/f/9e8a1a/32.png) [@fipa](https://www.ruby-forum.com/u/fipa)\
**Post date:** [April 1, 2009, 2:45pm UTC](https://www.ruby-forum.com/t/denormalize-db-by-adding-redundant-foreign-keys-to-tables/164442/1 "2009-04-01T14:45:02Z")

</div>

Hi,

I have 3 models: User, Order(user\_id), Membership(order\_id).

I’d like to know if a given user has a valid membership, i.e: the  
order.status == ‘paid’ and membership.expires\_at \> Time.now

I could use a User has\_many memberships :through =\> :order, and put a  
condition but that adds membership and order logic to the User model  
which I don’t want.

So my idea is to add a redundant user\_id to membership, and to set an  
expires\_at for a membership only when the order gets paid. This way I  
can’t easily query and it keeps the encapsulation of each model where it  
belongs to.

What do you think?

---

<div class="post-metadata">

**Author:** ![fipa](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/f/9e8a1a/32.png) [@fipa](https://www.ruby-forum.com/u/fipa)\
**Post date:** [April 1, 2009, 2:59pm UTC](https://www.ruby-forum.com/t/denormalize-db-by-adding-redundant-foreign-keys-to-tables/164442/2 "2009-04-01T14:59:02Z")

</div>

2009/4/1 Fernando P. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)

> which I don’t want.

I would always, as a first solution, look at what the question being  
asked  
is. You want to know if ‘a given user has a valid membership’,  
therefore  
use the User has\_many memberships option, I would not try to turn the  
question on it’s head to answer it.

---

<div class="post-metadata">

**Author:** ![fipa](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/f/9e8a1a/32.png) [@fipa](https://www.ruby-forum.com/u/fipa)\
**Post date:** [April 1, 2009, 3:25pm UTC](https://www.ruby-forum.com/t/denormalize-db-by-adding-redundant-foreign-keys-to-tables/164442/3 "2009-04-01T15:25:52Z")

</div>

> I would always, as a first solution, look at what the question being  
> asked  
> is. You want to know if ‘a given user has a valid membership’,  
> therefore  
> use the User has\_many memberships option, I would not try to turn the  
> question on it’s head to answer it.

Actually this post came as an echo to my previous one:  
[http://www.ruby-forum.com/topic/183084](http://www.ruby-forum.com/topic/183084)

I used to benefit from Rails ability to go through object associations  
so easily, and then it broke:

My Order model used to have a response\_code of type integer to handle  
the paid/unpaid status. And then I changed it to status of type string  
with the string ‘paid’/‘unpaid’.

An suddenly I realized that I had to go over various other models to  
make changes too. but that’s incorrect, if I change an attribute of the  
Order, I shouldn’t be changing things in other models too. Something was  
wrong.

So when I query for a paid Order and an expiry date that is in the  
future, where do I put the code?

I can’t put it in Order, because it would have to know about expires\_at,  
i can’t put it in membership, because it would have to know about the  
internal state attribute of Order which already broke on me.

So where to put it?

One solution is to refactor the code, and add a redundant user\_id to  
each membership record and if the expires\_at attribute is set to the  
future, then it means that the membership has been paid.
