Quick post about Rails DB relationships…

One mistake that I always seem to make is when it comes to choosing between a has_one/belongs_to relationship or simply a belongs_to relationship… I always forget which one should be used in which situation. Well now I’m writing it here so hopefully I remember!

Case 1)
has_one/belongs_to example: Let’s use an example to illustrate when this relationship should be use. So let’s say I have an Address model and a User model, and each user has exactly one DIFFERENT address. In this case I would use the ho/bt relation. This also assumes that the foreign key (user_id) should be stored in the Address table. Simple enough, but I was tricked (again) when I tried using it in a situation where for example each User does have an Address, but not a unique one (i.e. they have to pick from a list of 4-5 addresses). Sure this doesn’t make much sense in this context so let’s go to…

Case 2)
A simple belongs_to relationship. Let’s use a better example than the address one. Last week I was working on snippetslab and I wanted to add “theme” support (a theme is just basically a set of colors to use for syntax highlighting of the snippets). So I though: “Each user should have a theme, therefor, User has_one theme, and theme belongs_to User”. WRONG!… In this case I can’t really store my user_id in the theme table, since I only have 6 themes to offer, and all the users, even though they do HAVE ONE theme, those themes aren’t unique to every users. What needs to be used here seems a little tricky at first, but it makes sense. What I need to do is to store theme_id in my User table (so each user has a theme_id which consit of one of the 6 themes I’m offering) and as for the relationship, all I need to do is to add: belongs_to in my USER model… That’s right. User belongs_to Theme. No need to write anything in my theme model. And this took care of the problem!

It makes sense when you think about it, it’s just the syntax that makes it a bit confusing (At first you are tempted to think that A user has_one theme and a theme belongs_to a user, which is pretty much the case in theory…but in practice, well, it’s different!).

So basically to some it up: If model1 has_one (and EXACTLY ONE, UNIQUE) model2, and foreing key is stored in model2, use has_one/belongs_to. If model1 has one model2 (out of a fixed set, i.e. not one unique model2 per user), and your foreign key is stored in model1, then, model1 belongs_to model2 and that’s it.

Well hope this can help out anyone who is confused with the has_one/belongs_to relation!

Post a Comment

Your email is never published nor shared. Required fields are marked *

*
*