Your cart is currently empty!
Database Associations in Plain English
A lot of beginners (myself included) seem to run into issues when it comes to back end associations/relationships for database models…
NOTE: (this article is written in the context of ActiveRecord, so mostly applicable to Ruby programmers.)
I also find that using Figma (etc.) to draw out the relationships can lead to an illusion of understanding. Why an illusion? Because it often seems that you can translate whatever you had wrong in the verbal/written expression into an equally incorrect “visual expression/diagram”, and not even know it.
In other words: if you’re uncertain about how your associations play out, that uncertainty willy carry over to the diagram, but it will actually be worse because the picture (more tangible/concrete) than the words will reinforce whatever was wrong in the original abstraction.
The “solution” to this problem, in my opinion, is to think of associations in terms of “actions that we can write code for”. In Rails, declaring that something “has_many” or “belongs_to” is really for the sole purpose of “you the programmer” gaining access to built in methods/functions that allow you to chain code. Stuff like user.blogs.all…
To step back and look at this from a “high level” I think the confusion about “has_many” and “belongs_to” comes from the fact that we’ve spent all of our lives thinking about “has” and “belongs” in a certain way, and now when it comes to code… the meaning is slightly different.
To drive home the point, our default way of thinking in words (and what other can we think about this) is: we think of column headings in the context of “has”. If you have a user table, and there is a column for the user’s name, their email, their address etc… we automatically think of the table as “having” columns, for name, email etc. If you think about the columns individually then you are most definitely thinking “My user table HAS a name, HAS an email” etc.
Also, to play it in reverse, we think of a “name column” being on or “belonging to” a user table… is it any wonder there’s much confusion when it comes to designing associations? Especially when your mental-backend has such incredible “life momentum” to think about the word HAS or BELONG in one way?
To reduce my chances of getting confused, I’ll attempt to substitute the “code words” for almost-synonyms that seem more accurate to the task at hand. You don’t need to use my synonyms if you have something better, but try it out, you may discover a simple replacement of words reveals greater clarity in code.
For sake of example below, I’ll be using a “blogger” instead of a “user” since I think it makes the roles more explicit. (Further Explanation for Why Blogger As Opposed To Why User: a user might equally be a reader, subscriber, writer, etc…, all possible boolean columns on a single user.)
CONSIDER IN TYPICAL ASSOCIATION-RELATION SPEAK:
A BLOGGER has_many BLOGPOSTS
A BLOGPOST belongs_to a USER
A BLOGPOST has_many COMMENTS
A COMMENT belongs_to a BLOGPOST
A BLOGGER has_many COMMENTS through BLOGPOSTS
A BLOGGER has_many FRIENDS (other bloggers)
becomes…
A BLOGGER possesses BLOGPOSTS
A BLOGPOST needs a USER
A BLOGPOST possesses COMMENTS
A COMMENT needs a BLOGPOST
A BLOGGER can access COMMENTS because of BLOGPOSTS
A BLOGGER can access FRIENDS (other bloggers)
Essentially, POSSESS and NEED form a two way (has and belongs) relationship… if the relationship is “one way” (no belongs_to) or is indirect (with a “through”)… I think of it in terms of CAN ACCESS. Also, consider in Rails that if something “belongs_to” something else, you cannot even generate the row on the belongs_to table/model unless overriding standard procedure. In other words: if something BELONGS TO something else, it cannot exist unless the other things exists first; hence is NEEDS the thing that it belongs to.
For convenient reference:
has_many BECOMES “can access”
has_many and belongs_to BECOME “possess and needs”
belongs_to BECOMES “needs”
has_many through BECOMES “can access/because of”
There are other relationships such as the “many to many” “has one” and so on. Thinking about table relationships as actual relationships goes a log way (at least for me) to reducing the cognitive load of what’s happening behind the scenes. Also, from my own experience, you only need to consider this in tedium a handful of times before you can more simply look at the the phrases in “code vernacular” at translate into expectations immediately.