---
# System prepended metadata

title: Phase 3 Lesson 3. Twitter One to Many Relationship - AM

---

# Phase 3 Lesson 3. Twitter One to Many Relationship - AM

# One to Many Relationships

## Objectives

* Implement one object to many objects relationship
  * One object has many objects
  * One object belongs to another object
* Practice passing custom objects as arguments to methods
* Demonstrate single source of truth

## Reading Rspec Tests

- it
    - adds a label for a group of expectations
- describe
    - grouping a set of expectations or specifications about a part of our codebase
    - adds a heading for a group of `it` specifications
- expect
    - actually sets up an expectation that could cause a test failure. 
    - Expect recieves an object as an argument and allows us to attach matchers to it to check if our expectations are met.
- to
    - allows us to attach matchers to an expectation
- not_to
    - allows us to attach matchers to an expectation
- eq
    - an example of a matcher.

Check the docs for a list of [built in RSpec matchers](https://relishapp.com/rspec/rspec-expectations/docs/built-in-matchers)

Rspec is a gem (or library) containing methods that are designed to enable easy testing of behavior. It's a tool designed to help us work in a Behavior Driven Development pattern (BDD).

## Deliverables

* Create a User class. The class should have these methods:
  * `#initialize` which takes a username as an argument
  * a reader method for the username
  * `#tweets` that returns an array of Tweet instances
  * `#post_tweet` that takes a message as an argument, creates a new tweet, and adds it to the user's tweet collection
* Create a Tweet class. The class should have these methods:
  * `Tweet#message` that returns a string
  * `Tweet#user` that returns an instance of the user class
  * `Tweet.all` that returns all the Tweets created.
  * `Tweet#username` that returns the username of the tweet's user


First half of challenge:

```rb
class User
  attr_reader :username, :tweets

  def initialize(attributes = {})
    @username = attributes[:username]
    @tweets = []
  end

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


class Tweet

  @@all = []

  def self.all
    @@all
  end

  def self.all_messages
    self.all.map{|tweet| tweet.message}
  end

  attr_reader :message, :user
  # short for this:
  # def message
  #   @message
  # end

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

  def username
    user.username
  end

  def delete
    Tweet.all.delete(self)
    user.tweets.delete(self)
  end
  
end
```