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