Learning Object Relationships in Ruby with Pokémons
After spending the better part of my Sunday trying to understand Object Relationship, and still not getting anywhere near a lightbulb moment (not even a dim one), I travelled across the Internet land for the very best explanation, searching far and wide.
So I decided to take it further. In essence, object relationship is a concept used to illustrate how different instances of our classes can interact with one another, as with real-life situations. Our class instances can also be referred to as models. There are several basic ways in which models relate to one another—in this case, I’m going to practice the
belongs to and the
has many relationships.
In the world of Pokémons, you can
have many Pokémons (e.g. Pikachu, Eevee, etc.). In a reciprocal manner, those Pokémons
belong to you. And because you love Pokémons and you want to teach them more, each of your Pokémon also
has many moves and those moves
belong to each Pokémon with a specific type (e.g. electric, grass, etc.).
So let’s set up our three separate classes:
As we commit to become the very best trainer, like no one ever was, Prof. Oak called us to his lab and asked for our
trainer_name. At this point, we still have no Pokémons and our array starts empty. But no worries! We’ll earn our first starter Pokémon in no time!
Alright. Now, let’s set up our Pokémons! Since our Pokémons
belong to us, we are assigning
attr_accessor :trainer at the beginning of the class. Next, our class
Pokemon is responsible for recording all the Pokémons that we are going to encounter, and push them into our global variable
@@pokedex. When we encounter a new Pokémon, we also need to record its
pokemon_type, among other things, but we’ll keep it to these two for simplicity! And because we’re still a Lv 1 trainer, most of our Pokémons have not been taught any special moves yet, and our instance variable
pokemon_moves initiates to an empty array.
We’re also going to create a
Move class, not to complicate things, but because we promised to teach our best friends a few chops and kicks! Since we can only teach certain moves to Pokémons of a corresponding type, we also need to define
pokemon_type when we’re creating a new instance variable
Now, we’re done setting up! Let’s go back to our
Trainer class. We’ve chosen Pikachu as our first starter, and we need a method within our class to add Pikachu onto our slots. Our
#add_pokemon method will, well, add our Pokémon for us. And by assigning
self to our
pokemon.trainer, we automatically reciprocates the relationship between new Pokémon and ourselves, the trainer. Lastly, we can also check each Pokémon in our current slots using the
#pokemon_slots method, which will also helpfully tell us our Pokémon’s type.
So, let’s check on our code by calling on our methods!
Now, next, after levelling up some, we want to teach our friends some sick moves. How do we do that? We already have our
Move class, which we can use to call
new moves anytime. What’s next? We probably need to define some methods in our
Pokemon class so that we can assign a new move to a Pokémon. But our Pokémons can only learn moves that correspond to their types, so we need to code that conditional in as well. And finally, to look at all the moves each Pokémon knows, we use the
Let’s try calling our new methods!
All done! Here, we learn about how each class can use the informations in other classes to its advantage, especially with the help of
attr_accessors. We also learned about how to access those information and represent them as strings or array, using Ruby’s built-in
map method. We also used
self whenever we want to use objects (data and behaviour) to describe something. We got to practice some conditionals along the way, too. So that’s it! Hope that was as much fun for you as it was for me!
All flub-ups and boo-boos, if there are any, are mine. Any questions, shoot a message anytime! I don’t bite. Follow me on Twitter at @jouissances_.