One of the more useful tools that comes with Ruby on Rails is associations. This allows you to set up relationships between models to use built in functions to stream line your code for commonly used interactions. I will be heavily referring to the documentation included with Ruby on Rails, which I would recommend reading through when you have the time. For now I will highlight the most basic relationships that one is likely to use.
Associations make it easier to get models to have a connection that can be instantly referenced, allowing a coder to make a reference to a single model and, with that reference, also get information on all it's associated models.
Here are the relationships that come default with Rails and the ones you will interact with most:
- has_many :through
- has_one :through
To talk about what the differences between each relationship is I'll use a music app metaphor that is pretty common.
Let's start with the has_many and belongs_to: Any song written by that songwriter belongs to them, and couldn't exist if they weren't there to write it, so in the song model we would write:
class Song < ApplicationRecord belongs_to :singer end
And, because out singer owns the songs, we will change their model accordingly:
class Singer < ApplicationRecord has_many :songs end
This will allow you to, in the console, type out
And it will give you the models of each song associated with the first singer in the database!
The current setup makes the song model dependant and makes it to where a song can't be saved to the database unless you assign it to a singer. This can be useful in database management and also a source of debugging stress if you forget!
Note, because the singer will write more than one song it is a has_many and thus songs needs to be plural.
A good example of a has_one could be the singer's alias. Marshall Bruce Mathers III has_one professional alias, and it's Eminem. The use of has_one is benificial because it's not dependant. Let's add the steps for our alias class and singer class updates:
class Singer < ApplicationRecord has_many :songs has_one :alias end // class Alias < ApplicationRecord belongs_to :singer end
Notice that the has_one is singular! Now let's talk about through associations...Everyone knows that a well rounded artist doesn't shoehorn themselves into only one genre and style of music, wouldn't it be nice if we could find out what kind of genres a musician has performed with one simple keystroke? Let's set that up!
First, we need to show that songs can have genres. For simplicity sake we are going to say that every song has only one genre, so let's set up that relationship first:
class Song < ApplicationRecord belongs_to :singer has_one :genre end // class Genre < ApplicationRecord belongs_to :song end
Here's the fun part! We already know the song is associated with the singer, and the genre is associated to the song, all we have to is pass that connection along the chain! Our final set of model associations would look as follows:
class Singer < ApplicationRecord has_many :songs has_many :genres, through: :songs has_one :alias end // class Song < ApplicationRecord belongs_to :singer has_one :genre end // class Genre < ApplicationRecord belongs_to :song // class Alias < ApplicationRecord belongs_to :singer end
This will allow you to do things like the following which can make backend database management a lot easier and smoother.
Singer.first.genres Singer.first.alias Song.first.singer Song.first.genre Alias.first.singer
Until next time, happy coding!