Relationships in Rails
Tags: programming, beginners, ruby, rails
Published: 2023-01-20 04:10:37

`Databases` are an integral part of making most dynamic applications functional. When you log into Instagram or Snapchat, your specific information is what populates your screen. Your username, your photos, your feed filled with images from individuals that you follow; none of that would be possible without databases. They store all that information, which later populates the application's interface with the necessary data. For our examples, assume we are working with a stack that consists of a `ReactJS` frontend, a `Ruby on Rails API` that utilizes a `PostgreSQL database`. The API is the middle man that allows communication between the frontend and the database. 

##Why are Database Relationships Important?
Now that we have a bit of an overview of why databases are important to make your application work the way it should, let's discuss relationships between the different models in a database. Let us once again use the Instagram example. We have a user model and photo model. Each user has many photos that they have posted on their account. Each photo belongs to the user who posted the photo. It is important to define those relationships, because Rails gives us many tools to use those relationships to access your data more efficiently. 

## One-To-Many Relationship
The user to photo relationship is an example of a one-to-many relationship. Here is what we can type in the terminal to generate a user model:
```ruby
rails g model User username:string bio:text age:integer
```
This is a simple model with three attributes that define a user. Now to generate the photo model we can type this:
```ruby
rails g model Photo image_url:text caption:text user_id:integer
```
You may be wondering what the `user_id` attribute is for. It is known as a `foreign key` and it allows us to associate each photo with the correct user. When each instance of a user is created an id is automatically made, so when a new photo is posted by a user, their id will be saved in the new instance for that photo. We need to take one more step to get the full access to what Rails provides us.
```ruby
class Photo < ApplicationRecord
  belongs_to :user
end

class User < ApplicationRecord
  has_many :photos
end
```
The `belongs_to` and `has_many` macros are the last step we need to finalize the relationship between the two models. Now we can do things like this:
```ruby
user = User.first
user.photos
#will return all photos that belong to that user
```
The first line of code above gets us the first instance of a User and saves it in the `user` variable. You can then chain `.photos` to that user to return all the photos that were posted by that specific user. Rails allows us to retrieve all those photos quickly and efficiently instead of getting all the photo instances and finding all the ones with the matching `user_id`. Makes it much simpler for us coders, so we can focus on more complicated parts of our code instead of the simpler things. You can also find the user associated with each photo in a similar way.
```ruby
photo = Photo.first
photo.user
#will return the user that owns that photo
```
This code will find the user that posted that photo and return it. This is a quick summary of a one-to-many relationship, and how to instantiate it in Ruby.

##Many-To-Many Relationship
Now let's think of an example to highlight a many-to-many relationship. If we had an application where a student can join clubs and catch up with club news. We could have two model students and clubs. A student can be in many clubs, a club can have many students in it. In rails in order to create a many-to-many relationship between these two, we would need a joins table. To create a joins table we would do the following:
```ruby
rails g model StudentClub student_id:integer club_id:integer
```
This table's only job is store the the foreign keys for the student and club so rails can do the heavy lifting and create those associations for us. It is important to pay attention to syntax when creating the join table. It must be a combination of the two model names, as shown above. Now we must add the correct macros in the model files.
```ruby
class StudentClub < ApplicationRecord
  belongs_to :student
  belongs_to :club
end

class Student < ApplicationRecord
  has_many :student_clubs
  has_many :clubs, through: :student_clubs
end

class Club < ApplicationRecord
  has_many :student_clubs
  has_many :students, through: :student_clubs
end
```
Once you have added the above code to your files you are able to do the following:
```ruby
student = Student.first
club = Club.first
student.clubs
#will return all clubs student is apart of
club.students
#will return all student in the club
```
Make sure to pay attention to the syntax for everything because Rails needs that to make the associations work properly.

##One-To-One Relationship
The last relationship that will be discussed is a one-to-one relationship. This particular relationship probably won't be used as much as the last two, but it is still important to know. The example that will be used is the relationship between a state and its capital city. A state has one capital city and a capital city belongs to that state. The relationship can be defined with the following code:
```ruby
class State < ApplicationRecord
  has_one :capital
end

class Capital < ApplicationRecord
  belongs_to :state
end
```
You can then access the associated information in the ways we demonstrated earlier.

##Conclusion
The three relationships we discussed above are very important to understand in order to properly define your database in a way that works efficiently.

###Resources 
* [Active Record Associations](https://www.theodinproject.com/lessons/ruby-on-rails-active-record-associations) 
* [Active Record Associations - Ruby on Rails Guides](https://guides.rubyonrails.org/association_basics.html)