Part 4 – Building the Models and the Relationships
Now that our database has been created, we need to build the models that will interact with the database. Once again, this can all be done through artisan. If you go inside the app folder of your Laravel install, you will that there is the default User.php model that is built by default on a fresh Laravel install. We will go ahead and add our new models using artisan
php artisan make:model Hamburger php artisan make:model Description
We are using the ‘make’ namesapace and telling it that we want a model. We are doing it twice: once for hamburgers and once for descriptions. You will now see that both models have been created.
Based on the name of the class, Laravel will try to determine the table that you are using. So, Laravel would assume that:
- Our Hamburger model refers to our Hamburgers database table
- Our Description model refers to our Descriptions database table
If we had chosen non-standard model names or database names, then we would need to include additional code to define the mapping. That is why it is good practice to follow the Laravel naming conventions to make things easier. Here is what the generated Hamburger.php file looks like:
It basically creates a Hamburger model that extends the base Model class. Now we need to define the relationship with descriptions. We will use Laravel’s eloquent ORM (Object Relation Model), which helps define a lot of the object relationships.
The Eloquent ORM included with Laravel provides a beautiful, simple ActiveRecord implementation for working with your database. Each database table has a corresponding “Model” which is used to interact with that table. Using eloquent, you can query for data in your tables, as well as insert new records into the table. You can also setup relationships between the various models. One of the functions that are in eloquent is the hasMany() function. This will be used in the hamburger model to define the fact that the hamburger can have many descriptions. So let’s go ahead and add the following lines of code:
public function descriptions(){ return $this->hasMany(Description::class); }
The above function defines the relationship between the hamburgers and the descriptions. We have now confirmed that a hamburger has many descriptions. This sets up the one-way relationship from hamburgers to descriptions. Now, we need to create the other way relationship inside the Description model. And as you guessed, a description will always belong to one hamburger so we need to create the following function inside the desriptions model:
public function hamburger(){ return $this->belongsTo(Hamburger::class); }
So now we have configured both sides of the relationship so that if we have a hamburger, we can get all its associated descriptions. And if we have a description, we can find the corresponding hamburger.
One important thing that the model class allows you to do is basic validation of the data being sent to the database. This includes which fields can be entered by the user as user input and which cannot. In the case of a hamburger, the name, author and overview of the hamburger can be entered as user input. So we need to override the $fillable property which is empty by default and change it to:
public $fillable = ['name','overview','author'];
So what we are doing here is whitelisting the fields that can be user-submitted. This now says that these three field can be user-submitted for hamburgers. In other words, these fields can be filled out through a form. All fields not in this list will not be fillable. We will do the same for the description model by adding:
public $fillable = ['author','title','description'];
In the case of the descriptions model, we indicated that we wanted a soft delete in our migrations file. A soft delete marks a record in a database as deleted and prevents it from being selected. But the record is not physically deleted from the database. In order to actually delete the record, a “hard” delete or “permanent” delete must be performed. The advantage of a soft delete is that you can un-delete the record in the future if you choose. With a hard delete, once the record is deleted, it is gone forever. Since we want a soft delete, we need to use the SoftDelete trait. This is done by adding the following line to the model:
use SoftDeletes;
The entire Description model now looks like so:
namespace App; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\SoftDeletes; class Description extends Model { use SoftDeletes; // use the softdelete traits public $fillable = ['author','title','description']; public function hamburger(){ return $this->belongsTo(Hamburger::class); } public function scopeOfHamburger($query, $hamburgerId){ return $query->where('hamburger_id', $hamburgerId); } }
while entire Hamburger model now looks like so:
namespace App; use Illuminate\Database\Eloquent\Model; class Hamburger extends Model { public $fillable = ['name','overview','author']; public function descriptions(){ return $this->hasMany(Description::class); } }
Previous Step: Seeding the Database Tables
Next Step: Setting up the Routes