---
# System prepended metadata

title: 'Phase 3, Lesson 4. Twitter Many to many'

---

# Phase 3, Lesson 4. Twitter Many to many
## Goals
* Implement both sides of a many to many relationship
* Practice keeping groups of data related to instances of a class on the class as a class variable
* Demonstrate single source of truth by not storing collections of objects on other objects
* Demonstrate single source of truth for object relationships by emphasizing the connection between the belongs_to relationship and persistence.

How to follow along. We'll be reading through the specs as we write some code and test out the behavior. The `01_examples_spec.rb` file contains the rspec code we'll be running as we demonstrate what we know about relationships so far. The `02_exercise_spec.rb` file contains the rspec code you'll use when you work together to complete the many to many relationship between users and tweets in our twitter domain.

## Examples

For our examples, we'll be demonstrating:
1. how to implement a has_many, through relationship with a domain of `Aquarium`, `Exhibit` & `Fish`.
2. how to implement a many-to-many relationship with a domain of `Doctor`, `Appointment` & `Patient`.

## First Exercise

Work through the specs in examples.rb relating to the Doctor, Patient and Appointment classes. While you do, practice reading the words used in the specs (has_many, belongs_to, and has_many, through) to get a sense of what pattern you want to apply where. You can run:

```bash
rspec spec/01_examples_spec.rb:84 --fail-fast
```
to focus on appropriate specs
Whereever this line appears:

```
RSpec.describe "Many to Many Doctor <=> Patient through appointments" do
```

## Differences between our first Domain Model and the Second

Aquarium, Exhibit, Fish

Aquarium <= Exhibit <= Fish

Doctor, Appointment, Patient

Doctor <= Appointment => Patient
Picking out the Join model that connects both sides: Appointment.
Appointment is called a join model. It can establish a many to many relationship between the two models it belongs to.

Aquarium Exhibit
    - aquarium has many exhibits
    - exhibit belongs to aquarium
Auarium Fish
    - aquarium has many fish through exhibits
Exhibit Fish
    - exhibit has many fish
    - fish belongs to exhibit

Doctor
Appointment
Patient

Doctor Appointment
    - doctor has many appointments
    - appointment belongs to doctor
Doctor Patient
    - doctor has many patients, through appointments
    - patient has many doctors, through appointments
Appointment Patient
    - appointment belongs to patient
    - patient has many appointments
    
```rb
class Appointment
    appointment belongs to patient
    appointment belongs to doctor
end 

class Doctor
    doctor has many appointments
    doctor has many patients, through appointments
end 

class Patient
    patient has many appointments
    patient has many doctors, through appointments
end
```

![Has Many Through Diagram](has_many_through_diagram.drawio.png)

## Exercise

You can run the tests for the exercise with the following command:

```bash
rspec spec/02_exercise_spec.rb --f-f
```
This will give you one error at a time that you can work through. To start, you'll have this code already written: 

```rb
# user.rb
class User 
  @@all = []

  def self.all 
    @@all 
  end
  attr_reader :username
  def initialize(attributes = {})
    @username = attributes[:username]
    @@all << self
  end

  def post_tweet(message)
    Tweet.new(message, self)
  end

  def tweets
    Tweet.all.select { |tweet| tweet.user == self}
  end

end
```

```rb
# tweet.rb
class Tweet 
  @@all = []

  def self.all
    @@all
  end

  attr_reader :message, :user
  def initialize(attributes = {})
    @message = attributes[:message]
    @user = attributes[:user]
    @@all << self
  end

  def username 
    user.username
  end

  def delete 
    Tweet.all.delete(self) 
  end

end
```

```rb
# like.rb
class Like 
  @@all = []
  def self.all 
    @@all 
  end

  def initialize(attributes = {})
    @tweet = attributes[:tweet]
    @user = attributes[:user]
    @@all << self
  end
end
```

The basics of all 3 classes are built out for you, much like the finished code from the previous lecture on twritter_one_to_many. What's left to do is to add the association methods to this class to establish a many to many relationship between `User` and `Tweet` through likes.