The model is the most critical part of any web application; you could even call it the “brain” of your application. A good web application will be model-centric, with each resource being a representation of the model. In other words, the model sets the business logic for every resource, such as user, task, and so on.
In Laravel, you will usually use Eloquent ORM when building applications. Eloquent is a simple yet beautiful ActiveRecord implementation for working with a database. Each database table has a corresponding model, and without this model, you cannot query the data in the database table. Not only that, but the model plays a pivotal role in building relations between different tables.
For this reason, a model is also called an Eloquent model , and you use a flag like --migration, or simply --m, while creating a model through the terminal. In the previous chapter, you saw how to create a Task model along with the tasks table. You also have used a TaskController to manage the task resource. In the next sections, you will see how you can create tasks, and you will also see how you can use route model binding to edit your task resource.
Route Model Binding: Custom and Implicit
Here you inject a model ID to this controller action to retrieve the model that corresponds to that ID.
In the previous output, you can see that Method is GET, URI is tasks/{task}, and Name is tasks.show. This means the view Blade page is show.blade.php, and it belongs to the tasks folder. Finally, Action is AppHttpControllersTaskController@show.
This means Laravel has automatically injected the model instances directly into the routes. The route lists show that you can inject an entire Task model instance that matches the given ID.
Why does the route point to tasks.update, instead of tasks.edit? You can understand it better if you look at route:list, which tells you the action verb or method is tasks.update. Also, it points to the action TaskController@update.
This is part of the RESTful action on the resource model Task. What is happening here is that the generated controller will already have methods stubbed for each of these actions. Laravel is smart enough to include notes in its service container, informing you which URIs and verbs they handle. So, you don’t have to create the view page tasks.update in the resource/views/tasks folder. Through the RESTful resource controller, Laravel handles it.
Here you pass the task object as $task to tasks.edit, and Laravel is smart enough to guess that it is an instance of the Task model.
Implicit Route Binding
Laravel automatically resolves Eloquent models defined in routes or controller actions, as in public function edit(Task $task){}, whose type-hinted variable names match a route segment name. Since the $task variable is type-hinted as the AppTask Eloquent model and the variable name matches the {task} URI segment, Laravel will automatically inject the model instance that has an ID matching the corresponding value from the request URI.
Now if you want to edit the task with an ID of 2, the URI is http://localhost:8000/tasks/2/edit, and you get the same effect.
Custom Route Binding
By the way, you can customize the key name also. Suppose you have another database column other than ID and that database column is named slug .
Now instead of the ID, you can pass slug as an instance of the task resource like before.
Model Relations
An application in Laravel mainly depends on model relations. Therefore, this section is one of the most important sections in the book. Up to now, you were trying to understand how the Laravel Model-View-Controller logic works. Now the time has come to build a small article management application. While building this application, you will learn about some other key components of Laravel. In the next chapter, I will go deeper into the database and Eloquent ORM components, and you will see how these relational operations work through models and how controllers control the workflow between models and views.
Building models from scratch is, no doubt, a cumbersome job, so Laravel has taken care of this in an elegant way. By default, Laravel comes with only the User model, but you can configure it according to your requirements. In most applications, however complicated they are, you do not have to touch the default User model installed by Laravel. You can add any extra columns in the users database table. According to the MVC pattern, the model talks to the database, either retrieves data from the database or inserts it, updates the data, and passes it to the controller. Then, the controller can pass it to the views. Conversely, the controller takes input from the views and passes it to the model to process data.
The User model interacts with the users database, and in the same way, other models will work in tandem with the other tables to run the article management application smoothly. In this application, you have many separate resources, such as articles, users, profiles, comments, and so on. These resources will interact with each other through models. Laravel has made the process super simple and expressive.
Behind the scenes, Laravel handles a huge task, which is evident from these simple expressive functions. Consider a few scenarios where a user has many comments. It is obvious that a user should be able to comment as much as they want. They should also be able to comment on another user’s profile. So, the comment object may have a polymorphic relationship with two model objects: Article and Profile. One user may have many articles too. Now, each article may have many tags, and many tags may belong to many articles.
Therefore, you can see many types of relations here: article to user and the inverse (one-to-one), one user to one profile (one-to-one), one article to many tags (one-to-many), many articles to many tags (many-to-many), and comments to articles and profiles (polymorphic).
Note
A polymorphic relationship is where a model can belong to more than one other model on a single association, such as comments belonging to the articles and profiles table records at the same time.
Before taking a look at the models, you must perform your migrations, covered next.
How Migrations Work with the Laravel Model
For the sake of building the example application, let’s start with the database. I could have started with controllers and views or I could have discussed the model, but database migration is a good option because you are going to see how to create a completely database-driven application. This migration has a direct relation with the models.
You will see how it works in a minute.
Here, I would like to add one key concept: object-relational mapping (ORM). As an intermediate PHP user, you are probably already acquainted with this concept; yet, a few lines about it won’t hurt you, as Laravel has managed this feature magnificently via Eloquent ORM. Mapping the application object to the database tables has been one of the greatest challenges of using Laravel; however, Eloquent ORM has solved this problem completely. It provides an interface that converts application objects to database table records and does the reverse too.
What does this mean? It is a default name of the table used for the project’s migration status. Don’t change it.
Redis is an open source, fast, key-value store; among other things, you can manage cache and session data with it.
By default, the database is homestead; you can use this one, or you can change it accordingly. I have created a database called laravelmodelrelations and connected it with my Laravel application through this .env file.
Now, using migration, I can build my database tables and relate them with each other using some simple default methodology.
Keeping your application logic in your mind, you need to design the tables. Laravel comes up with two tables: users and password-resets . You do not need to change the second one. However, if needed, you can change the users table. Here, you don’t do that, because you will have a separate Profile table where you will add some more information about a user. Besides, you need to build other tables as your application demands.
The first model, called Profile, has been created under the app folder. Next, you should work on the profiles table before running the migration.
I could have added more functionalities such as first name, last name, and so on, but I didn’t do that for brevity. Currently, our purposes will be served by only city and about. The interesting part is of course user_id. Each profile is connected with a single user.
Let me explain what you are doing here. By using a single command like php artisan make:model Comment -m, you create a model comment, and at the same time Laravel creates a related comments table for it.
Now, before running the migration, you should plan your application and add functionalities to your newly created tables based on code 4.9.
This code does the same thing, only in an inverse way. Each profile should belong to one User model. To speed up your application, let’s add functionalities to other tables and after that define the relationship accordingly.
You’ll also want to create a Role model and roles table because you want your users to have some certain privileges such as Administrator, Moderator, and Member. Therefore, you need a pivot table like role_user.
One user may have one role or many roles at the same time.
At the same time in your pivot table role_user, add two columns, as shown here:
I have not touched the comment table currently, for one reason. You will work on that table at the end phase of building your content management application. This is because the comment table will have polymorphic relations with other tables. I will discuss it in the next chapter.
Since you have migrated your tables, you can now populate them with fake data. It can be a tedious job to add fake data manually. Laravel has taken care of that so you are able to test your application with fake data.
Model and Faker Object
Take the third user; the user’s name is Van Gorczany, and the e-mail ID is [email protected]. Now through that dummy e-mail, you can log in to your application. Every user has one password, which is secret.
You have migrated all tables except Comment. You have dummy data inside the tables; therefore, you can now build the relations, and after that, you can use resource controllers and views to show how these model relations work perfectly.
Examining the Home Page
The article object directly accesses the user object and gets the respective name associated with that article. How does this happen? This is a good example of a one-to-one relationship. If you click the link, you will reach the user’s page and can read all the articles written by that user. You need to understand one thing: every article belongs to one user, and you can access that user from that article. Laravel model relations handle that behind the scenes. To make them work properly, you have to define them in the models.
The next step will be to check all the models and finally define the relationship between them so that they can talk to each other to fetch the respective data. After that, you will build the resource controllers and views to complete the whole setup.
Currently, this model has one component missing, which is Comment. You will add it in the last stage. From the previous code, it is evident that the user has one profile, has one article, and many articles.
You have your database tables ready with dummy data. You have made your models ready to maintain the relationship among the objects. So, the time has come to make resource controllers. After that, you will build your views to test that your application works.
Relations Between Model, Database, and Eloquent
- 1.
Laravel creates a connection.
- 2.
Laravel selects a database; you know these parts, such as user name, password, etc have been defined in the .env file.
- 3.
Usually, the third step is the most complicated one: performing a database query. Laravel’s Eloquent ORM handles that complicated part in such a decent manner that you don’t have to worry about it.
- 4.
After that, Laravel automatically closes the connection. I have already discussed this topic in great detail.
The index() method will present the home page where you can show every comment in one place. Through the show() method , you can show each comment. While showing each comment, you can also show who the commenter is. The possibilities are endless. At the same time, by using this resource controller, you can create/store, edit/update, and finally destroy the comment object.
I have also changed the main route. In the previous process, you used an anonymous function to return the view; now you are taking that view under the main() method of ArticleController.
Creating Views to Show Relationships
For the first phase of your application, you are ready to create the views. You have seen the welcome.blade.php page. To articles along with other associated objects, you are going to learn how to create three more view pages. They are index.blade.php, show.blade.php, and articles.blade.php.
You loop through the articles item and grab four articles on each page, and the code {{ $articles->render() }} gives you the pagination links.
This is where you find all the tables related to the respective models. You must understand the naming conventions that Eloquent ORM follows. When you create the model on the command line, Laravel creates a table for that. By convention, the snake_case plural name of the class has been used as the table name. You saw that for the Article model, a table articles has been created. You didn’t tell Eloquent which table to use for your Article model. By default, it has chosen the name. First, in the ArticleController using the index() method , you start retrieving data from the database. Here the Eloquent model has acted as a powerful query builder allowing you to fluently query the database associated with the database.
This has brought a massive change in the whole structure of the main page at http://localhost:8000. You have used constraints to choose the user_id set to 1 and ordered the titles in descending order. The four records have been taken from the database.
You saw before how this logic looks in the home page (Figure 4-3). In the left sidebar panel, you are showcasing the articles by the user (with an ID of 1).
As you see, methods like all() and get() retrieve multiple results. Actually, an instance of IlluminateDatabaseEloquentCollection has been returned. This Collection class provides many helpful methods for working with the Eloquent results. In this case, you can loop over the collection like an array.
It is true that a user has many articles; likewise, it is true that a particular article belongs to a particular user.
In the next chapter, you will see those relations in great detail.