Creating a has_many/belongs_to relationship in Rails
Tags: beginners, rails, ruby, hasmanybelongsto
Published: 2021-02-28 07:46:50

[Completed Example Code](https://github.com/colerau/people)

This article will cover how to set up a basic Rails relational database. Our example database will have two models (Ruby classes): `Person` and `Interest`. We will say that a person has many interests, and an interest belongs to a person. A person will have the attributes `name` and `age`; an interest will have the attributes `activity_name` and `person_id`. 

Below is a visual representation of our database:
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ppcgtd63j1ow88rz0psr.png)

# Step 1: Navigate to your Rails project or create a new one

You'll want to be inside of your Rails project for the following steps. If you do not have one:
* assuming you have _Ruby_, _SQLite3_, _Node.js_, _Yarn_, and _Rails_ itself downloaded to your computer,
* In Terminal, navigate to the folder you want your Rails app to reside in.
* Enter the command `rails new {lowercase and no spaces app name}`
* Enter the command `cd {lowercase and no spaces app name}`
* Open up your text editor.

## Example

I'm making a Rails app called `People` so I will, in Terminal, navigate to the folder I want my Rails app to be in, then:
* run the command `rails new people`
* run the command `cd people`
* run the command `code .` to open up VSCode.

# Step 2: Inside your text editor, create the Person model

In Terminal, in your Rails app directory, enter 
`rails g model NameOfModel column_name:datatype column_name2:datatype2 --no-test-framework`

## Example

To make the `Person` model, I'll enter in Terminal
`rails g model Person name:string age:integer --no-test-framework`. Now I have a SQLite model called `Person` that has the attributes `name` (a string), and `age` (an integer).

# Step 3: Create the Interest model

Follow the instructions in Step 2 but for the Interest model. 

## Example

To make the `Interest` model, I'll enter in Terminal
`rails g model Interest activity_name:string person_id:integer --no-test-framework`. Now I have a SQLite model called `Interest` that has the attributes `activity_name` (a string) and `person_id` (an integer). 

**_The model that "belongs to" another model will have the attribute `lowercase other model's name_id.`_** **_That is why, in our example case, the `Interest` model has an attribute of `person_id`._**

# Step 4: Add the has_many relationship

In the model that "has_many", add the code such that your file looks like this:

```ruby
class ModelThatHasMany < ApplicationRecord
  has_many :{lowercase name of model this model has many of}
end
```

## Example

Since a person has many interests, we will add the `has_many` relationship to the `Person` model. 

In `app/models/person.rb`, I will make the file look like the following: 

```ruby
class Person < ApplicationRecord
  has_many :interests
end
```

I'm telling Rails that an instance of my `Person` class will have many interests. 

# Step 5: Add the belongs_to relationship

Identify the model that belongs to another model.

In the model that belongs to another model, add the following code:

```ruby
class ModelThatBelongsToAnotherModel < ApplicationRecord
  belongs_to :{name of model this model belongs to}
end
``` 

## Example

Since an interest belongs to a person, we will add the `belongs_to` relationship to the `Interest` model. 

In `app/models/interest.rb`, I will make the file look like the following: 

```ruby
class Interest < ApplicationRecord
  belongs_to :person
end
```

I'm telling Rails that an instance of my `Interest` class will belong to a person instance.

# Step 6: Run rails db:migrate in Terminal

In Terminal, enter the command `rails db:migrate` to create your database with the code you've already written. 

# Step 7: Write some seeds

In `db/seeds.rb`, create some instances of your classes (models), then type in `rails c` in Terminal to test out the relationships. 

## Example

We want to see if a person truly does have many interests and if an interest truly does belong to a person. 

To do that, we'll create some seeds to later test out in the rails console.

In `db/seeds.rb`, add the following code: 

```ruby
# person1 will have an id of 1
person1 = Person.create(name: "Steve", age: 34)
# person2 will have an id of 2
person2 = Person.create(name: "Alex", age: 29)
```

This code creates two person instances. "Steve" will have an id of 1. "Alex" will have an id of 2. 

Now add some more code to the seeds.rb file:

```ruby
# person1 will have the following interests
interest1 = Interest.create(activity_name: "walking", person_id: 1)
interest2 = Interest.create(activity_name: "playing the viola", person_id: 1)
# person2 will have the following interests
interest3 = Interest.create(activity_name: "reading", person_id: 2)
interest4 = Interest.create(activity_name: "playing the piano", person_id: 2)
```

This code creates four interest instances. Taking into consideration that "Steve" has an id of 1, since interest1 has a person_id of 1, interest1 will belong to "Steve". Since interest2 has a person_id of 1, interest2 will belong to "Steve". "Steve" now has many interests (interest1 and interest2). 

Taking into consideration that "Alex" has an id of 2, since interest3 has a person_id of 2, interest3 will belong to "Alex". Since interest4 has a person_id of 2, interest4 will belong to "Alex". "Alex" now has many interests (interest3 and interest4). 

# Step 8: Test out the relationships in the Rails console

Entering the rails console will allow us to play around with our model instances and how they are related to each other. 

## Example

In Terminal, I'll type in `rails c` to enter the Rails console.

I want to see if my model instances are associated correctly. According to my seeds.rb file, Steve's first interest should be walking. It's relevant to note that Steve has an id of 1. Therefore, if I type into the console `Person.first.interests.first.activity_name`, `"walking"` should be returned. 

Does the interest of "walking" belong to Steve? To test this out, I'll type into the console `Interest.first.person.name`. This should return `"Steve"`. (`Interest.first` is the walking interest since the walking interest has an id of 1). 

***

[Completed Example Code](https://github.com/colerau/people)