Download as pdf or txt
Download as pdf or txt
You are on page 1of 7

dev.

to

Mastering Laravel Eloquent ORM - The


Eloquent Journey (PART 2)
10-13 minutes

Understanding Eloquent Relationships

Welcome once again. In this post I will be diving into Laravel


Eloquent Relationships, if you missed the previous article, the link
can be found at the bottom of this post.

As we all know that databases tables are often related to one


another, let take for instance in a blogging platform, the users' table
will be related to the posts, comments and replies tables, the
comments table will be rated to the posts table, replies related to
the comments table. Eloquent comes packed with the underlying
structure to enable us to manage the relations between our
database tables, thereby making queries between our tables simple
and flexible.

Eloquent supports many types of relationships, which includes:

One To One

One To Many

Many To Many

Has One Through

Has Many Through

One To One (Polymorphic)

One To Many (Polymorphic)

Many To Many (Polymorphic)

Eloquent relationships are defined as methods in our model


classes. The method names are decided by you, but make sure to
give a name that can explain your relationship.

One To One

The One to One relationship is a type of relationship whereby a


model is related to another model by a single data. let's say we
have Profile Model that will hold the profile information about a user
in our database. We will expect our users to have only one profile
and a profile should belong to a single user. This kind of
relationship is a one to one relationship, and to achieve this
relationship, we will expect our profiles table to have a connection
to our users' table using the foreign key constraint by adding a
column to create this connection.

Sample Profile table

id user_id address

1 1 20 Markson St.

$table->unsignedInteger('user_id')

$table->foriegnKey('user_id')->references('id')->on('users')->onDelete('cascad

adding the above to our profile table migration, laravel now uses
this to create our relationship between our models.

we can now define our relationship between our models. since the
foreign key is on the Profile model, we can now use the eloquent
hasOne() method to let eloquent bind our User model to the
profile model that a user in our users' table has a profile by

/**
*Returns an Eloquent relationship
**/
public function profile()
{
return $this->hasOne(Profile::class);
}

Here eloquent expect that we have a user_id column existing in


the profile table, but in suituation you have a different column name
for our foriegn key representing our users table,

id custom_user_id address

1 1 20 Markson St.

we can tell Eloquent by providing the second parameter to our


hasOne() method

return $this->hasOne(Profile::class,
'custom_user_id');

Eloquent also expect that on our user table the primary key is id,
but in cases we have a different primary key other that id,

Sample User Table

user_id name

1 Samfield Hawb

we can pass the third parameter

return $this->hasOne(Profile::class,
'custom_user_id','user_id');

with this we have a relationship between the User model and


Profile model. Now let create a reverse of the relationship using the
Eloquent belongsTo() method. we will define the reverse now in
our Profile Model class;

/**
*Returns an Eloquent Relationship
*/
public function user()
{
return $this->belongsTo(User::class);
}

Also here eloquent will try to match user_id on the profiles table
with an id on the users' table, and in situation you have a different
column name for our foreign key on our profile table,

id custom_user_id address

1 1 20 Markson St.

we can tell Eloquent by providing the second parameter to our


belongsTo() method

return $this->belongsTo(User::class,
'custom_user_id');

Eloquent also expect that on our user table the primary key is id,
but in cases we have a different primary key other than id,

user_id name

1 Samfield Hawb

we can pass a third parameter

return $this->belongsTo(User::class,
'custom_user_id','user_id');

With this set up, we can now use this relationship to perform a
query between this two models

$user = \App\User::find(1);
$user->profile;//the profile can now be gotten
by

//likewise in the opposite direction


$profile = \App\Profile::find(1);
$profile->user; //gets the user that owns the
profile
$profile->user->name; //returns the name of the
user

One To Many

This is a relationship whereby a model is related to another model


by many records, for instance, A user in a blogging application can
have many blog posts, comments, as well as replies, likewise a
comment, post, or replies can belong to a user in the users' table.
Eloquent provides us with hasMany() method to create this kind of
relationship between our models. So let's define this kind of
relationship between a User model and a Post Model, in a User
model we add;

Sample Posts Table

id title content user_id

1 Mastering laravel Eloquent ORM content 1


public function posts()
{
return $this->hasMany(Post::class);
}

here Eloquent expect a foriegn key column user_id in our posts


table, but i situation we have a different name,

id title content custom_user_id

1 Mastering laravel Eloquent content 1


ORM

a second parameter can be pass to the hasMany() method,

return
$this->hasMany(Post::class,'custom_user_id');

likewise if we have a diffent primary key for the parent model User
from the id column which Eloquent expect, we can also pass in a
third parameter to the hasMany() method

return
$this->hasMany(Post::class,'custom_user_id','user_id')

we have created a relationship for our User model to the Post


model. Now let create the reverse of the relationship, Post model to
the User model, this can be achieve also with the Eloquent
belongsTo() method ;

public function user()


{
return $this->belongsTo(User::class);
}

here eloquent will still try to match user_id on the posts table with
an id on the users' table, in situation you have a different column
name for our foreign key on our posts table, we can tell Eloquent by
providing the second parameter to our belongsTo() method

return $this->belongsTo(User::class,
'custom_user_id');

Eloquent still expect that on our user table the primary key is id,
but in cases we had a define primary key name other that id, we
can pass a third paramater to the belongsTo() method;

return $this->belongsTo(User::class,
'custom_user_id','user_id');

with this set up now, we can now make use of eloquent to query
data between the models. Lets get all the posts made by a user
with id of 1 from the database;

$user = \App\User::findOrFail(1); //we retrieve


the user

//lets print out the title for all the post made
foreach ($user->posts as $post)
{
echo $post->title;
}

we have seen how easy eloquent has made retrieving the post
here, with this relationship, we can create a post that binds to a
particular user;

$user = \App\User::find(1);
$user->posts()->create([
//we supply all keys representing the column
name and the value in
// 'key' => 'value'
]);

with the above code snippet, Eloquent automatically extracts the


user_id from the $user object to create a blog post. likewise,
using the createMany() method on the relationship can allow you
to store many blog posts at a time to a user. We will come to this
later.
Let's say we want to get the name of a user that owns a post, we
can easily achieve this too from the relationship;

$post = \App\Post::find(1);
echo $post->user->name;

Many To Many

At times when building a web application, we want to related values


in a table with other values in another, for instance, if we want to
introduce a role system into our blog, a user can have multiple
roles, also a role can belong to multiple users. Laravel Eloquent
provides us with the many to many relationships, to achieve this,
we will need to create another table using the laravel migration that
will store up this relationship, create_role_user_table,

$ php artisan make:migration


create_role_user_table --table=role_user

in the up method of our generated migration file, we can add

$table->unsignedInteger('user_id');
$table->unsignedInteger('role_id');
//foriegn key

$table->foriegnKey('user_id')->references('id')->on('users')->onDelete('cascad

$table->foriegnKey('role_id')->references('id')->on('roles')->onDelete('cascad

here, eloquent uses these two columns to fetch our data when
needed.

Sample role_user table with data

user_id role_id

1 1

1 4

1 3

2 4

We can see how this user with id 1 has 3 roles with ids 1, 4,
3.
Now on our User model we can now define our relationship using
the belongsToMany() method provided for use by Eloquent
Model class

public function roles()


{
return $this->belongsToMany(Role::class);
}

Eloquent seeing this relationship will try to determine the table for
we created above by joining the two related models in alphabetical
other separated by an underscore role_user. In situations we
declared a name other than this, we can pass a second parameter
to our belongsToMany method to tell Eloquent where to find the
relationship.

return
$this->belongsToMany(Role::class,'custom_role_user');

Also, if we had custom keys for the table other than the expected
value, we can pass the third parameter as a foreign key for the
model we are defining the relationship and a fourth parameter for
the foreign key to the relating model

return
$this->belongsToMany(Role::class,'custom_role_user','custom_user_id','custom_r

we can then define the inverse of the relationship on our role model
too, which will enable use query all users that is tied to a particular
role.

public function users()


{
return $this->belongsToMany(User::class);
}

With the relationships define, we can then fetch our data from the
database using eloquent ORM;

$user = \App\User::find(1);
foreach ($user->roles as $role)
{
echo $role->name
}

$role = \App\Role::find(1);
foreach($role->users as $user)
{
echo $user->name;
}

we can assign a role to a user using the relationship and the


attach() method from the Model class

$user = \App\User::find(1);
$user->roles()->attach(1); //assigned role with id
1 to the user

$user->roles()->attach([2,3,4]); //assigned roles


with ids 2,3,4 to the user

also roles can be remove from users using the eloquent detach()
method;

$user = \App\User::find(1);
$user->roles()->detach(1); //remove role with id 1
to the user
$user->roles()->detach([2,3,4]); //remove roles
with ids 2,3,4 to the user

Conclusion

So far we have covered the One to One, One To Many, and


Many To Many relationship types made available by eloquent, in
the next article we will look into the remaining types. Thank you for
following this far.

Links to Previous articles:

Mastering Laravel Eloquent ORM - The Eloquent Journey (PART 1)

You might also like