4. Laravel models explained - adaptdk/developer-meeting-nova GitHub Wiki

Laravel models explained

When you create models in Laravel using Artisan make:model they are stored in the app folder.

Your models are born quite empty like this :

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Brand extends Model
{
	// 
}

Make mass-assignment possible

The framework guards attributes on your Models, so you need to tell which attributes are available for changing / setting data on.

You have the following options for this:

  • protected $guarded = [] tells explicitely which attributes are guarded making all other attributes changeable.
  • protected $fillable = [] tells which attribute can be changed. All others are guarded.

Adding one-to-many relationship

A brand can be possible for many different cars, so we define this as a one-to-many relationship. On the Brand model we add the following function.

NOTE: The function cars() is in plural as a brand can have multiple cars.

public function cars() {
	return $this->hasMany(Car::class);
}

Brand model

<?php
namespace App;

use Illuminate\Database\Eloquent\Model;

class Brand extends Model
{
    /**
     *
     * @var array
     */
    protected $fillable = [
        'name',
    ];

    /**
     * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
     */
    public function cars()
    {
        return $this->hasMany(Car::class);
    }
}

Color model

The Color model does not differ from a Brand (except from the class name), so it looks like this:

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Color extends Model
{
    protected $fillable = [
        'name'
    ];

    /**
     * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
     */
    public function cars() {
        return $this->hasMany(Car::class);
    }
}

Car

You only need to add two field to $fillable as the rest will be added through the relationships.

protected $fillable = [
    'model_type',
    'description'
];

Car BelongsTo relationship

We add BelongsTo for the following : Brand, Color, Dealership and Order. You will add 4 functions that looks like the following. Just change the function name and class name.

public function brand()
{
    return $this->belongsTo(Brand::class);
}

Car model

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Car extends Model
{
    protected $fillable = [
        'model_type',
        'description'
    ];


    /**
     * @return \Illuminate\Database\Eloquent\Relations\HasOne
     */
    public function brand()
    {
        return $this->belongsTo(Brand::class);
    }

    /**
     * @return \Illuminate\Database\Eloquent\Relations\HasOne
     */
    public function color()
    {
        return $this->belongsTo(Color::class);
    }

    /**
     * @return \Illuminate\Database\Eloquent\Relations\HasOne
     */
    public function dealership()
    {
        return $this->belongsTo(Dealership::class);
    }

    public function order()
    {
        return $this->belongsTo(Order::class);
    }
}

Adding a many-to-many relationship

A dealership will have many different sellers, but seller can also be selling car from one dealership on mondays and another on fridays, so we need to define a many-to-many relationship on our model.

NOTE: You already created a table for this earlier called dealership_seller which will hold dealership_ids and seller_ids.

Many-to-many relationship in code

Dealership

On the Dealership model you add the following

public function sellers() {
    return $this->belongsToMany(Seller::class);
}
Add orders relationship

You would also like to have a relationship where a Dealership can have a relationship to Orders, so you can get the orders that a single Dealership has.

Add the following:

public function orders() {
	return $this->hasMany(Order::class);
}

Dealership model result

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Dealership extends Model
{
    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = [
        'internal_name',
        'street_name',
        'city'
    ];

    public function sellers() {
        return $this->belongsToMany(Seller::class);
    }

    public function orders() {
        return $this->hasMany(Order::class);
    }
}

Seller

You basically add the same on the Seller model, just pointing toward the Dealership.

public function dealership() {
    return $this->belongsTo(Dealership::class);
}

Seller model result

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Seller extends Model
{
    /**
     * @var array
     */
    protected $fillable = [
        'name',
    ];

    public function dealerships() {
        return $this->belongsToMany(Dealership::class);
    }
}

Customer

Our customer is a very simple model, so we add name to $fillable and add Order as a relationship. Your model will look like this:

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Customer extends Model
{
    /**
     * @var array
     */
    protected $fillable = [
        'name'
    ];

    public function orders() {
        return $this->hasMany(Order::class);
    }
}

Order

On Order we only got the warranty_expires field and belongTo relationship for Car, Customer, Dealership and Seller.

Your model will look like this:

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Order extends Model
{
    /**
     * @var array
     */
    protected $fillable = [
        'warranty_expires',
    ];

    public function customer() {
        return $this->belongsTo(Customer::class);
    }

    public function car() {
        return $this->belongsTo(Car::class);
    }

    public function seller() {
        return $this->belongsTo(Seller::class);
    }

    public function dealership() {
        return $this->belongsTo(Dealership::class);
    }
}