Skip to content

Creating Models

Adarsh Kumar Maurya edited this page Nov 28, 2018 · 1 revision

Creating Models

So now that we’ve spent a lot of time making sure the database is all configured and we have all the migrations all ready to go, we’ll shift over and spend a little bit more time in the code. So we’ll start off by building some models that will work with the database tables that we’ve created.

So we’re going to build a product model and a description model and we’re going to be using Artisan to build those as well.

One of the first things that we need to do though, just like we deleted the default migrations that came with Laravel when we installed it, there’s also a user model that’s been installed that we don’t need any longer.

Adarsh:product-service adarshmaurya$ rm -f app/User.php

So we’ll delete that guy first. Now if we go take a look at our App directory in our project you can see that we don’t have any models configured right away. So we’ll jump back over to the terminal and then we’ll use Artisan to generate a couple models for us.

So we’re going to use that make namespace again. So PHP Artisan make and in this case we’re going to use the model command. So this one only takes the one argument that just tells it what’s the name of the model we want. So we’ll do one for Product. And then we’ll do one for Description.

Adarsh:product-service adarshmaurya$ php artisan make:model Product
Model created successfully.
Adarsh:product-service adarshmaurya$ php artisan make:model Description
Model created successfully.

Now when we go over and take a look at our project again, you can see now that we have a couple classes in the root of our App directory. We have our Description model and we have our Product model.

So, for the sake of our project, we don’t need to do a lot to change these models because there’s a lot of default behavior that’s baked into the core Eloquent model that do a lot of work for us.

One of the things that’s already baked in is that it attempts to decide what the database table is that you might be using based on the name of the class itself.

So in this case, because our database tables are descriptions and products, and we have a model called product and description, it’s already going to assume that we’re using the lowercase pluralized form of the model, so we actually don’t make a declaration for that. However, if we were using a different database table that was not the automatically inferred version of that, we could add some attributes here to help direct the model to the correct database.

So, for the most part, we don’t need to make any adjustments to these models to get stock behavior, but what we want to do now is we actually want to make sure that these models know about those relationships that we configured.

So the first thing that we’re going to do, is we’re going to tell the product model what we need to do to define the descriptions relationship.

So in order to do that we just need to add a quick method, a quick public method to the Product model. And the name of this method is going to be descriptions(). And so what this method’s job is is to define the relationship with descriptions. So one of the built in features of Eloquent is that they have these relationship objects already built in, so there’s a very handy syntax that we can just say the descriptions simply need to return an object called has many.

So this has many object is doing a lot of work for us, but all we have to do is pass in one parameter which tells the ORM which other model is actually the relationship with. So to do this, we could use some PHP syntax to make sure that we’re just saying description class and this shorthand that I’m using here is something that showed up in PHP 5.5. And so it basically just turns into a string that is the entire namespace and class name of that class. But it’s shorthand, it’s a lot shorter to do this. So we just do description colon colon class and that will turn into the full path for the description class.

Description is just a keyword? It is a class in the App namespace. It is the other model. But it has to be named descriptions? Where does that get referenced from? How does it know that Descriptions is going to return an object?

So if we work our way in and then back out, Description is the actual class name in the namespace App, so it shares the namespace with the current model, which is Product. And what we basically want to do is we want to pass a string that is the namespace path for the Description model so that Eloquent knows which model to assign to that relationship for has many, and then this Descriptions method itself on the Product model is going to return the relationship object.There’s a lot more sort of magic to how Eloquent works, that you could spend an entire afternoon kind of learning about that, but the thing that you want to remember is that it just is a relationship object that’s being returned, it’s not actually doing any sort of math or returning the actual collection itself at this time. It’s simply making a reference to the descriptions() method being a kind of a pointer to the relationship that it has with the Description model.

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Product extends Model
{
    public function descriptions(){
      return $this->hasMany(Description::class);
    }
}

So this is the one way relationship from Product to Descriptions, and again we just need to pass in the path to where the ORM can find the other model that needs to have the other side of the relationship.

But this is only one way. So to build the counterpart to this, what we want to do is we want to go into the Description model and we want to create a public method that’s called Product, singular because it only belongs to one product and in this similar case here, we want to do this belongs to and then here we’ll pass in, much like we did on the other side, the Product class.

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Description extends Model
{
    public function producy(){
      $this->belongsTo(Product::class);
    }
}

So now we’ve configured both sides of the relationship such that if we have in our possession a product, we can get all of its descriptions and if we have ourselves a description, we can get its corresponding product.

So it’s very lightweight on the syntax side, and like I said there’s a lot of like internal plumbing that’s going on to make it work, and right now this is kind of what we need to just move forward. Does it make sense? Makes sense. Cool.