Intro to OOP: Ruby 'One to Many' vs 'Many to Many'

mzakzook

mzakzook

Posted on October 22, 2019

Intro to OOP: Ruby 'One to Many' vs 'Many to Many'

As a Ruby beginner, I started off learning the basics - hashes, arrays and methods. These building blocks will continue to show up again and again. But how do these 'building blocks' come together?

When faced with the challenge of modeling real-world paradigms, Classes opened new doors to the possibilities of code. In Ruby, the use of Classes to create relationships is known as Object Oriented Programming (OOP). An individual instance of a Class is known as an Object or Instance.

When designing the relationships among Classes I find it helpful to first distinguish: am I dealing with a 'one to many' relationship or a 'many to many' relationship?

An example of a 'one to many' relationship is: a sports team and its players. A player only has one team (let's disregard outliers like Bo Jackson) and a team has many players. To connect classes that fall into this category, I would add an attribute, intended to store an entire object of the 'one' class, to the 'many' class. For our team example this means adding a 'team' attribute, intended to store a team object, to the Player class.

class Player
    attr_accessor :team
    attr_reader :name, :position
    @@all = []

    def initialize(name, position)
        @name = name 
        @position = position
        @@all << self
    end
end

class Team
    attr_reader :name, :city
    @@all = []

    def initialize(name, city)
        @name = name
        @city = city
        @@all << self
    end

    def players
        Player.all.select { |player| player.team == self }
    end
end

With the above 'players' method inside the Team class I am able to find a team's roster (all of its players), and this is possible because of the 'team' attribute inside the Player class.

An example of a 'many to many' relationship is: a social media app and its users. A person uses many social media apps and a social media app has many users. This scenario calls for a Join class. Let's run through how it looks...

class User
    attr_reader :name, :email
    @@all = []

    def initialize(name, email)
        @name = name
        @email = email
        @@all << self
    end
end

class App
    attr_reader :name, :url
    @@all = []

    def initialize(name, url)
        @name = name
        @url = url
        @@all << self
    end
end

class Account
    attr_reader :user, :app
    attr_accessor :username, :password
    @@all = []

    def initialize(user, app, username, password)
        @user = user
        @app = app
        @username = username
        @password = password
        @@all << self
    end
end

In the above example, I created three classes: a User class, an App class and an Account class. The User class only captures information about a person: her/his name & email. The App class only captures information about a social media app: its name and url. And the Account class captures all User and App information (by initializing an Account object with a User object and an App object), as well as information that is specific to an account: its username and password. A user does not inherently know about the app(s) she/he uses and an app does not inherently know about its users, but they are connected through accounts.

With an 'Accounts' join class in place, I am now able to keep track of all user/app relationships, and call on methods belonging to either class. For example, if I wanted to see all of the apps for a specific user I could write...

class User  
    ...
    def apps
        my_accts = Account.all.select {|acct| acct.user == self}
        my_accts.map {|acct| acct.app}
    end
end

Designing your Class relationships from the start will allow you to hit the ground running when you're ready to write your code. And realizing when you're dealing with a 'One to Many' vs a 'Many to Many' relationship should simplify your design process.

💖 💪 🙅 🚩
mzakzook
mzakzook

Posted on October 22, 2019

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related