Laravel Eloquent Relationships: A Guide for Advanced Users (r) (r)

Jun 10, 2023
Two people hugging and learning about Laravel relationships

Please share the news with

There is a time and opportunity for any programmer need to communicate to databases. This is when the point that Eloquent is transformed into the Laravel object-relational modeler (ORM) lets you interact in a process with tables in the database. It is simple and quick.

As an expert, you are aware of and know the six most important types of relationships that will be discussed and reviewed.

What is the relationship Eloquentians have with their language?

When working with tables within your relational database, you can recognize relationships through the link between tables. This lets you manage and arrange your data efficiently which allows for better readability as well as the handling of data. There are three kinds of databases which are utilized for real-time data:

  • one-to-one - One record within the table may be linked to one in it is only one table. A name, for example or Social Security number.
  • One-to-many could be associated with several records in another table. Similar to a writer, blogs and.
  • multiple entries in tables are linked to several records in a different table. These include students as well as their courses that they're enrolled in.

Laravel offers a simple way to handle connections and manage them to databases with an object-oriented syntax within Eloquent.

In addition to those definitions, Laravel also adds other connections that comprise:

  • There's an array of ways to go through
  • Polymorphic Relationships
  • Polymorphic

Take, for example an online store that contains a variety of articles, all of which fall under a particular category. Therefore, splitting databases into multiple tables makes sense from an operational point of viewpoint. Each table comes with its own problems of its own, since you may not wish to go through each table.

It's possible to establish an initial one-to-many relationship with Laravel for us to assist during times the time you're interested in knowing more about the product. we are able to do this with the help of the model of Product.

Database schema with three tables and a joint table representing a polymorphic relationship
A database schema that comprises three tables, as well as a joint table, which is a representation of the polymorphic relationship

One-to-One Relationship

In the first relation Laravel gives, they link two tables in a way to ensure that the row from the table can be connected to one row only from the other table.

To get a better understanding of this matter, it's important to develop two models incorporating each movement:

php artisan make:model Tenant Php artisan make:model Rent

This situation involves two models. The first is the tenant in addition to the other being their rent.

hasOne(Rent::class); 

It is because it decides to establish the foreign key relationship with the model's parent title (Tenant in this case) and Rent models assume that there is an ID for the tenant as an an external key.

We can easily alter the method this manner, by adding an argument utilize the method isOne: method: isOne method:

Return"$this" >hasOne(Rent::class, "custom_key");

Eloquent will assume that there's a match between the specified external key with the main key of the parent (Tenant Model). It will by default look for the ID of the tenant that is associated with the key ID key within the record of Tenants. You can overwrite the tenant's ID by making use of a different argument within the isOne. is One method. In this instance, it's aligned with a different key

return $this->hasOne(Rent::class, "custom_key", "other_key"); 

When we've discovered the one to 1 relation between models and the models, we are able to utilize the relationship in a straightforward manner like This:

$rent = Tenant::find(10)->rent;

In this particular line, it will calculate the tenant's rent with the 10th number if there is the ID is present.

One-To-Many Relationship

In the same way as the relation that was previously discussed, this one will establish the connection between single parent models aswell as models that have multiple children. There is a good chance that a tenant won't be only paying one rent payment because it's a regular installment. Therefore, it's likely to be a series of installments.

Our previous relationship was not ideal, and is something we can rectify:

hasMany(Rent::class); 

Before we start the procedure of calculating rents, an important concept to consider is that relationships can be query builders. So you can add further constraints (like rent due within during the interval between dates, a minimum payment or minimum payment.) and then connect them in order to get the desired result:

$rents = Tenant::find(10)->rent()->where('payment', '>', 500)->first();

Similar to the first, it is possible to overwrite both foreign and local keys with the following argument:

return $this->hasMany(Rent::class, "foreign_key");
return $this->hasMany(Rent::class, "foreign_key", "local_key");

Now we have all the data on the rent being to be paid by tenants, but what do we do if we have the amount of the rent but want to find out where the tenant's origin is? It is possible to use belongingsToproperty. isToproperty:

belongsTo(Tenant::class); 

The house is now available for lease. home easily

$tenant = Rent::find(1)->tenant;

When using isTo as an isTo technique, we can additionally overwrite both keys as local and foreign keys exactly as it was previously done.

It's just one of the many connections

Since our Tenant model was specifically designed to work with multiple Rent models, it's crucial to have access to the most up-to-date or relevant model of the relationship.

The best way to accomplish this is through combining the hasOne ofMany with ofMany methods:

public function latestRent() return $this->hasOne(Rent::class)->latestOfMany(); public function oldestRent() return $this->hasOne(Rent::class)->oldestOfMany(); 

In default, we're provided with the relevant data for the key that is used as the primary. Data is then processed. However, it is possible to create the filters you want using this technique. ofMany method.

return $this->hasOne(Rent::class)->ofMany('price', 'min');

HasOneThrough and HasManyThrough Relationships

A traversalmethods show that the models that we use will have be able to move through several models to make an alliance with the intended model. In this case, for instance, we could connect the Rent to the Landlord. But, it is required that the rent go through the Tenant before it can reach the Landlord.

Table keys are required for this look like:

rent id - integer name - string value - double tenants id - integer name - string rent_id - integer landlord id - integer name - string tenant_id - integer

Once we've imagined what our tables will look like, we can make these models:

hasOneThrough(Landlord::class, Tenant::class); 

The main reason for using the hasOneThrough is that the primary reason to use this technique is to access the model you'd prefer to access The second issue is what model which you'll navigate through.

Like in the past you can change both local and foreign keys. As we now have two keys, it is possible to have two copies of the following sequence:

public function rentLandlord() return $this->hasOneThrough( Landlord::class, Tenant::class, "rent_id", // Foreign key on the tenant table "tenant_id", // Foreign key on the landlord table "id", // Local key on the tenant class "id" // Local key on the tenant table ); 

Likely, it is likely that the "Has Numerous Through" relationship in Laravel Eloquent is a useful feature when you're trying to get access to information in an unreachable table via the intermediary table. Consider the following example with three tables:

  • the nation
  • users
  • Games

Every country has a variety of players. Each User is involved in numerous Games. We aim to find all Games that are associated with a specific country by using the User table.

Tables are described this way:

country id - integer name - string user id - integer country_id - integer name - string games id - integer user_id - integer title - string

Then you need to build an Eloquent model for each table you own:

hasMany(User::class); public function games() return $this->hasManyThrough(Games::class, User::class); 
belongsTo(Country::class); public function posts() return $this->hasMany(Post::class); 
belongsTo(User::class); 

Following this step, we'll be able to use to call the game()method of the Country model to access any game, since we've discovered there is a "Has Many Through" relationship between Country and Game by using the User model.

games;

Many-to-Many Relationship

The connection between a large number of people is more intricate. One good example of this is someone who has many different roles. It is also possible to have a role given to a variety of employees. This is the reason for the multi-to-many relationship.

In order to accomplish this to accomplish this, we must include the employee, roles, and rolestables.

The table structure of databases will look like this:

employees id - integer name - string roles id - integer name - string role_employees user_id - integer role_id - integer

Based upon the structure of the table in the relationship, it's straightforward to determine our employee model to be part of the belongToMany Role model.

belongsToMany(Role::class); 

When we have defined the function, we can access all roles of employees and also filter them into:

$employee = Employee::find(1); $employee->roles->forEach(function($role) // ); // OR $employee = Employee::find(1)->roles()->orderBy('name')->where('name', 'admin')->get();

Similar to other techniques, we could replace both local and foreign keys using belongsToMany. belongsToMany method.

To define the inverted relationship of belongsToMany, you need to define the inverted relationship. You can use the exact same method, however using the child method and using parents as arguments.

belongsToMany(Employee::class); 

The reason for The Intermediate Table

You may have noticed that when using the many-tos-many relationship in any case, we're required to use an intermediary table. In this instance we're using the employee_job_employees table.

The default pivot table contains only ID attributes. If we would like to include more attributes, we'll have to add them using the following method:

return $this->belongsToMany(Employee::class)->withPivot("active", "created_at");

If we want to reduce the pivot of time, you can do this:

return $this->belongsToMany(Employee::class)->withTimestamps();

Another thing to be aware of is that it is possible to alter the term "pivot" according to our needs. We like it to match our needs to better suit our needs:

return $this->belongsToMany(Employee::class)->as('subscription')->withPivot("active", "created_by");
return $this->belongsToMany(Employee::class)->wherePivot('promoted', 1); return $this->belongsToMany(Employee::class)->wherePivotIn('level', [1, 2]); return $this->belongsToMany(Employee::class)->wherePivotNotIn('level', [2, 3]); return $this->belongsToMany(Employee::class)->wherePivotBetween('posted_at', ['2023-01-01 00:00:00', '2023-01-02 00:00:00']); return $this->belongsToMany(Employee::class)->wherePivotNull('expired_at'); return $this->belongsToMany(Employee::class)->wherePivotNotNull('posted_at');

The other amazing feature is the capability to place orders via pivots:

return $this->belongsToMany(Employee::class) ->where('promoted', true) ->orderByPivot('hired_at', 'desc');

Polymorphic Relations

The term Polymorphic comes from Greek that means "many kinds of." The app's layout could encompass many different kinds of connections and could include more than one connection. Imagine we're creating an application with blog posts, videos as well as polls. Users can leave comments on each of them. Therefore, the style for commenting can be found in Blogs, Videos, and even Polls examples.

The One To One Polymorphism

This kind of relationship is similar to the normal one-to-one relationship. The only different is that the child model could be associated with multiple kinds of models with the same relationship.

Consider, for instance, an instance of an example of a Tenantand Landlord model. It may have an inter-polymorphic relationship to WaterBill. WaterBill models.

Table structure could be as follows:

tenants id - integer name - string landlords id - integer name - string waterbills id - integer amount - double waterbillable_id waterbillable_type

The waterbillable_id column is used for identification purposes of the tenant, tenantor landlordwhile the waterbillable_type is the name of the class used by the parent model. The type column is employed in a way that's clear, to identify the model that is generating.

A definition model of this kind of relationship would include:

morphTo(); class Tenant extends Model public function waterBill() return $this->morphOne(WaterBill::class, 'billable'); class Landlord extends Model public function waterBill() return $this->morphOne(WaterBill::class, 'billable'); 

Once everything is set up, we'll be able to gain access to data about both Tenant and the Landlord models.

waterBill; $landlord = Landlord::find(1)->waterBill;

The Polymorphic One to Many

Like the traditional one-to-many relationships. There is a major difference the fact that children models can be a part of different types of model by using one association.

On a social media site such as Facebook it's possible to comment on videos, posts and polls in real time. Through a polymorphic model that can be used to create multiple tables, we could make one table that can be used to store comments table to keep the feedback for the various types of categories accessible. The structure of our table will be as follows:

posts id - integer title - string body - text videos id - integer title - string url - string polls id - integer title - string comments id - integer body - text commentable_id - integer commentable_type - string

The commentable_id is the id of the record. Commentable_type refers to the class's type, and the person who speaks well can identify what they are looking for. The model's structure is very similar to polymorphic ones-to-many

morphTo(); class Poll extends Model public function comments() return $this->morphMany(Comment::class, 'commentable'); class Live extends Model public function comments() return $this->morphMany(Comments::class, 'commentable'); 

To retrieve comments that were posted on the live stream, we need to utilize the Find method, making use of the ID. now we have access to the class that allows comments:

comments as $comment) // OR Live::find(1)->comments()->each(function($comment) // ); Live::find(1)->comments()->map(function($comment) // ); Live::find(1)->comments()->filter(function($comment) // ); // etc.

If we are the owners of the comments and want to find out who wrote them We can use comments via the Commentable Method:

Commentable type that allows commenting to Post, Video, or Poll Live

Polymorphic one of Many

There are many applications that have a large number of users, they require an efficient and quick method for interacting with models and also between models. The need may arise for the user's primary or final post that can be achieved using a mix of the MorphOne or ofMany methods:

morphOne(Post::class, 'postable')->latestOfMany(); public function oldestPost() return $this->morphOne(Post::class, 'postable')->oldestOfMany(); 

The two methods of most up-to-dateOfMany as well as olderOfManyare using the most recent or earliest model, which depends on the model's first primary, which is the requirement to be sortable.

Sometimes, we don't need to organize the articles with ID. Maybe we changed the date of publication for certain posts, but we need to organize them according to the order in which they were released, not according to the ID number.

It is done by simply transferring two parameters into ofMany. ofMany is a method that can assist with this. The first element is the principal that we must select. Another parameter concerns the method of sorting:

morphOne(Post::class, "postable")->ofMany("published_at", "max"); 

In this way, you can create further higher-level connections with these! Think about this example. You are required to create an inventory of articles currently in the news that were published in order of when they were published. This can be a challenge when we have two articles with the same publication date and also when posts are scheduled to publish in the near future.

In this way, you can pass the order we want to apply the filters, using ofMany. ofMany method. This way we'll sort the posts in accordance with published_at. And when they're similar and the order of publication will be determined by ID. In addition, we can include the query function to ofMany in this ofMany technique to block the posting of all articles that need to be published!

hasOne(Post::class)->ofMany([ 'published_at' => 'max', 'id' => 'max', ], function ($query) $query->where('published_at', '

Polymorphic Many to Many

The polymorphic model for many-to-many objects is far more complicated than the regular one. The most common situation is that tags are applied to a variety of objects in your app. In the case of TikTok there are tags which can be applied to video stories and shorts, as well as other types of media.

The polymorphic many-to-many allows us to build tables of tags that can be used for videos, shorts, as well as stories.

Table structure is very straightforward to grasp:

videos id - integer description - string stories id - integer description - string taggables tag_id - integer taggable_id - integer taggable_type - string

Once the tables are ready once the tables are ready, we can create the model and use the MorphToMany method. The method accepts names for the class of the model along with the names of the relationships':

morphToMany(Tag::class, 'taggable'); 

And with this it is simple to create an inverted relationship. Each model which has children, we could use the term as"morphedByMany". morphedByMany procedure.

morphedByMany(Story::class, 'taggable'); public function videos() return $this->morphedByMany(Video::class, 'taggable'); 

If we are given tags that we'd want to apply for We are able to find all the videos and stories that are associated with the tag!

stories; $videos = $tag->stories;

Improve Eloquent in order to speed up

Laravel is a powerful caching system that works with multiple backends, such as Redis, Memcached, and caching that is based on files. By caching the outcomes of the queries, it is possible to reduce the volume of queries to databases and make your app more efficient and much more efficient.

Additionally, you can make use of Laravel's queries builder to construct more intricate queries, which will also improve the performance of your application.

Summary

Eloquent relation are a powerful feature of Laravel that allows programmers to efficiently deal with data which is linked to one another. From one-to-one to many-to-many relationships Eloquent is a slick and intuitive syntax to define and examine the relationship.

This post was first seen on here

This post was first seen on here