# 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
```

## 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.