Table of Contents

Model Relationships

Model Relationships

A zombie developer is not very good at relationships, whereas a Laravel developer is great at implementing database relationships.

Zombies lack the intellegence to build meaningful relationships.

Laravel's Eloquent class gives us the ability to easily create and use relationships between tables.


Model Relationships

Relationships are a way of binding data between tables. Let's say for instance, that you have a blog which has a 'posts' and a 'comments' table.

These two tables have a relationship. a POST can HAVE MANY COMMENTS, and a COMMENT will BELONG TO a POST. The relationship between the POST to COMMENTS is referred to as a HAS MANY relationship, and the relationship between the COMMENTS and POSTS is referred to as a BELONGS TO relationship.

Using our Zombie table from above we are also going to create another table called weapons:

weapons

Field Type Length
id INT 11
zombie_id INT 11
name VARCHAR 50

Notice the 'zombie_id' row in the table above.

This references the 'id' row in the Zombies table, and is referred to as a Foreign Key which occurs when a row in one table uniquely identifies a row in another table. This Foreign Key is what ties a relationship between the Weapons table and the Zombies table.

Let's say that we already have two weapons in our database that belong to each of our zombies:

In the example above you can see that we have added two rows to our weapons table. We have added an "Axe" that belongs to a zombie with an ID of 2 and we have a "Shot Gun" which belongs to our zombie with an ID of 1.

Next we need to create our Weapon Model so our app can talk to the weapons table, we'll create this file at app\Weapon.php:

<?php namespace App;

use Illuminate\Database\Eloquent\Model;

class Weapon extends Model {

    protected $table = 'weapons';

}

Now, we could always display information about our zombie including their weapon by adding the following code:

<?php

use App\Zombie as Zombie;
use App\Weapon as Weapon;

Route::get('/zombie/{id}', function($id){
    $zombie = Zombie::find($id);
    echo 'Name: ' . $zombie->name . '<br />';
    echo 'Strength: ' . $zombie->strength . '<br />';
    echo 'Health: ' . $zombie->health . '<br />';

    $weapon = Weapon::where('zombie_id', '=', $zombie->id)->first();
    echo 'Weapon: ' . $weapon->name . '<br />';
});

We just introduced another new helper provided by the Eloquent library; this is the where function. Before we just used find which returned the object with an ID.

Above we are using Weapon::where('zombie_id', '=', $zombie->id)- >first();. What is happening here is that we want to get the weapon where the zombie_id is equal to our zombie id, and we want to get the first row.

You can learn more about all the different ways to retrieve data from our models by checking out the full documentation on Eloquent here: http://laravel.com/docs/eloquent.

The above example will get the job done; however, there is an even easier way of doing this. If we specify our relationship between the zombie and the weapon we can minify the amount of code we need to add. We could add our relationship to our Zombie Model, and that would look something like this:

<?php namespace App;

use Illuminate\Database\Eloquent\Model;

class Zombie extends Model {

    protected $table = 'zombies';
    protected $fillable = ['name', 'strength', 'health'];

    public function weapon()
    {
        return $this->hasOne('App\Weapon');
    }
}

Above we are saying that a Zombie has one Weapon. We just create a new public function called weapon() and return the weapon.

So, with that addition to our Zombie Model we can now refactor our code from above and display all the information about our Zombie like this:

<?php

use App\Zombie as Zombie;

Route::get('/zombie/{id}', function($id){
    $zombie = Zombie::find($id);
    echo 'Name: ' . $zombie->name . '<br />';
    echo 'Strength: ' . $zombie->strength . '<br />';
    echo 'Health: ' . $zombie->health . '<br />';
    echo 'Weapon: ' . $zombie->weapon->name . '<br />';
});

How great is that! By adding that relationship we just took these two lines of code:

$weapon = Weapon::where('zombie_id', '=', $zombie->id)->first();
echo 'Weapon: ' . $weapon->name . '<br />';

and turned it into this one line:

echo 'Weapon: ' . $zombie->weapon->name . '<br />';

Being more readable and easier to work with, If we now visit (site.com/zombie/1) we should get our output which will look like the following:

To see all the information about our zombie with an ID of 2 we could then visit (site.com/zombie/2)

One last thing before we move on, what if we had the ID of our weapon and we wanted to see to which zombie it belonged? This can be achieved in the same way.

We can add our relationship in our Weapon class, but instead of the hasOne relationship, we will use the belongsTo relationship since a Weapon belongs to a zombie. To add this relationship we will add a zombie method to our Weapons model that will return a Zombie object like so:

<?php namespace App;

use Illuminate\Database\Eloquent\Model;

class Weapon extends Model {

    protected $table = 'weapons';

    public function zombie(){
      return $this->belongsTo('App\Zombie');
    }
}

Now, we could add the following route:

use App\Weapon as Weapon;

Route::get('/weapon/{id}', function($id){
  $weapon = Weapon::find($id);
  echo "This " . $weapon->name . " belongs to " . $weapon->zombie->name;
});

We can now get to the zombie that owns this weapon by accessing $weapon->zombie. And if we were to visit (site.com/weapon/1) we would get the following output:

Using relationships in Laravel makes interacting with your data easy and fun.

The relationship between hasOne and belongsTo is referred to as a One-to-One relationship (since each of them has one of the other). If you wish to learn about the other relationships in depth head on over to http://laravel.com/docs/eloquent-relationships.

Models and relationships are a big part of what makes Laravel amazing. Instead of creating complex queries and bloated models, we can focus on the fun stuff and build our application quicker than ever before.

Next up we are going to talk about mutators, which allow us to manipulate(mutate) data before it gets entered into or retrieved from the database.