Ruby Object Oriented Programming: The Has Many Through Relationship

James Miele
Jul 30, 2017 · 5 min read

Let me preface this by saying that my previous life didn’t involve much coding at all. Actually, let me rephrase that… my previous life didn’t involve any coding at all. However, on my journey to becoming a better and happier person, a change of career path was step 1.

I was always a strong math student and loved logical thinking. My best friend was a Comp Sci major and I often sat down next to him while he walked me through some of the projects he did for class. As I followed along I said to myself, “this is cool stuff!” Let’s fast forward…

It was week two of my tech bootcamp with Flatiron School (oh yeah, that’s right… I quit my job and decided to pursue a career in web development) and I couldn’t seem to grasp the concept of a single-source-of-truth when dealing with a has-many-through relationship.

What is this “single-source-of-truth” you speak of?

I’m glad you asked! Let’s get started on understanding this whole “has many through” relationship, and what it means to abide by our single-source-of-truth…

What is a single-source-of-truth?

Wikipedia on Single Source of Truth

Whoa. Let me highlight the most important information for you to take from this excerpt:

again, Wikipedia on Single Source of Truth

If you take away only one thing from that excerpt, make sure it’s what I highlighted. Now, store that definition in memory (pun intended), we’re going to refer to it very shortly.

What is a has-many-through relationship?

I’m going to use an artist and a museum for this example. An artist and a museum are connected to one another through artwork. An artist has many pieces of artwork and a museum has many pieces of artwork. This is called a has-many has-many relationship.

This is what that relationship looks like. an artist has many artwork and a museum has many artwork.
I prefer to look at the relationship like this. An artist has many artwork and they can get to museum because artwork points to a museum.
And the opposite can also be said.

Okay, so now that we understand that… what do I mean when I say “an artist and a museum are connected to one another through artwork”?

A piece of artwork belongs to one artist (usually) and belongs to one museum (I’m talking originals only here…). So if this piece of artwork had a brain, we could say it knows about the museum that it’s in and it knows about the artist that created it, right? Right.

So if I was an artist, I wouldn’t want to remember every museum my artwork is in because that’s a lot of information to store. Instead, when artwork is purchased by a museum, since our artwork has a brain, we can just ask it what museum it belongs to. So I know museums through my artwork.

Alright dude, I get it… but how does this look in code and what does all of this mean when I’m trying to code these relationships..?

Let’s start with our Artist class because without an artist, we have no artwork, and without artwork, who needs art museums, right?

If you don’t understand this code, I’d recommend taking Introduction to Ruby, what we’re about to discuss will require some understanding of classes!

Alright, so here’s what we have so far, I’ve added in-line comments to explain what’s going on. But wait — artist#create_artwork calls on Artwork.new. Why? As I said before, without an artist, we have no artwork, so our artwork will always be initialized from the artist. Since this method depends on our Artwork class to function properly, I’m going to jump over to that class to fill in the required information.

But wait — we said an artist knows about his or her artwork… how do they know? Don’t we have to keep track of it?

Yes! And this is where our single-source-of-truth comes into play.

We know that an artist is supposed to know about their artwork, and a museum will also know about the artwork it has on display, and we’ve already established that Artwork is our connection between Artist and Museum…

So if we wanted to store an array of our artwork, where do you think the best place to store that array is?

If you said in our Artwork class, great, that means some of this is making sense. If you said something else, I’d recommend reading a little more on a single-source-of-truth.

Alright! We’ve almost got our entire has-many-through relationship! Our last step is adding a Museum class and having that museum buy_artwork to put on display!

Museum.all will return an empty array until artwork is bought or you pre-populate some previously bought artwork before running.

Notice! By calling our method museum#buy_artwork, we set an instance of Artwork’s ‘museum’ attribute equal to self (which is an instance of museum right now). But wait! I don’t remember Artwork having that attribute… Well, let’s go ahead and give it that attribute so our method works as intended.

NOTE: I gave the initialize method an OPTIONAL argument of museum, that defaults to nil (since creating artwork shouldn’t require being in a museum!)

Alright awesome! Now we can create artwork with an artist, have that artwork stored upon creation, and then have a museum buy that artwork and update the current information. So now that we have all of the information we need all in one place, how do we access information in the Artist class, from methods in the Museum class?

If you’re taking a flight from New York to Milan that CONNECTS through Rome, you could say you can’t get to Milan without going through Rome.

If you’re in the Artist class and want to get to the Museum class, you have to first go through Artwork! Our Artwork.all array stores all of our information, that’s our connecting flight!

Let’s give each of our classes the information they need about their connecting flight!

Added: Artist#21:25, Museum#18:20

That’s it! You’ve just established a has many through relationship that utilizes a single source of truth!

Here’s some of the methods our Artist and Museum classes get THROUGH Artwork:

I encourage you to create an environment file that requires each of your class.rb files, put some test cases in with pry, and run your environment file in the terminal. This will allow you to call each of your methods and see how we use Artwork as a bridge between Artist and Museum!
Example environment file

That’s all on this topic for now!

James Miele

Written by

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade