Relationships

Database tables are often related to one another. For example, a car can only have one manufacture, or a user can have multiple cars for sale. Where relationships are deined is inside the App\Model\Service. The OrmModel makes managing and working with these relationships easy, and supports several different types of relationships:

One To One

A one-to-one relationship is a very basic relationship. Lets say for example that you have a car, a car has one manufacture so to define this relationship:

 <?php
 namespace App\Model\Service;

[...]

 class Car extends OrmModel\Service\AbstractService
 {

     public function __construct([...])
     {
         [...]
         /**
          * Get the manufacture record associated with the car.
          */
         $this->hasOne(Manufacture::class);
     }
 }

One To Many

A one-to-many relationship is used to define relationships where a single model owns any amount of other models. For example, a manufacture has multiple cars.

<?php
namespace App\Model\Service;

[...]

class Manufacture extends OrmModel\Service\AbstractService
{

    public function __construct([...])
    {
        [...]
        /**
         * Get the cars of the manufacture.
         */
        $this->hasMany(Car::class);
    }
}

Belongs To

Now that we can access to all of the manufactres cars, let’s define a relationship to allow a car to access its manufacture. To define the inverse of a hasMany relationship, define a relationship function on the child model which calls the belongsTo method:

<?php
namespace App\Model\Service;

[...]

class Car extends OrmModel\Service\AbstractService
{

    public function __construct([...])
    {
        [...]
        /**
         * Get the manufacture that owns the car.
         */
        $this->belongsTo(Manufacture::class);
    }
}

Many To Many

Many-to-many relations are slightly more complicated than hasOne and hasMany relationships. An example of such a relationship is a car with many bodyworks, where the bodyworks are also shared by other cars. For example, many cars may have the bodywork of “Sedan”. To define this relationship, three database tables are needed: cars, bodywork, and car_bodywork. The car_bodywork table is derived from the alphabetical order of the related model names, and contains the car_id and bodywork_id columns.

Soo let’s see how this in code looks:

In the Car model we should add the hasManyToMany. The first parameter is the link table. In our case thats CarBodyworks we then link this to the Bodywork table/model.

<?php
namespace App\Model\Service;

[...]

class Car extends OrmModel\Service\AbstractService
{

    public function __construct([...])
    {
        [...]
        /**
         * The bodywork that belong to the car.
         */
        $this->hasManyToMany(CarBodyworks::class, Bodywork::class);
    }
}

We do the same in our Bodywork model we do the same but reversed:

<?php
namespace App\Model\Service;

[...]

class Bodywork extends OrmModel\Service\AbstractService
{

    public function __construct([...])
    {
        [...]
        $this->hasManyToMany(CarBodyworks::class, Car::class);
    }
}

Now inside the CarBodyworks we need to define 2 hasManyToMany relationships:

<?php
namespace App\Model\Service;

[...]

class CarBodyworks extends OrmModel\Service\AbstractService
{

    public function __construct([...])
    {
        [...]
        /**
         * Makes The link between the car and the bodywork.
         */
        $this->belongsTo(Bodywork::class);
        $this->belongsTo(Car::class);
    }
}

Entity annotation

With a many-to-many relationship you have to specify what variable belongs to the relationship. You do that with annotations inside your entities.

Inside our src/Model/Entity/Car.php we have the following variable $bodywork . That is the link between our car and our bodyworks. we only need to do this inside our car model.

<?php
/**
 * @var HasManyToManyInterface
 */
public $bodywork;

This also works with an one-to-many relationship. src/Model/Entity/Manufacture.php

<?php
/**
 * @var HasManyInterface|Car[]
 */
public $car;

Attach

If you want to connect a many-to-many you can use attach. so lets say for example we want to insert a new car, but we also need to create a link inside the CarBodyworks database table. we can make use of the attach function:

<?php
$newCar->bodywork->attach($bodywork);

This will attach a bodywork object. If you want to create a link with an id you can do so by:

<?php
$newCar->bodywork->attachById(1);

Detach

In our example we detach an car from its bodywork:

<?php
$carModel->detachById(2);

We have now deleted the car but the link is still there. With the detachBy function we can detach an array of cars:

<?php
$carModel->detachBy([1, 2, 3, 4, 5]);

We can also detach all the cars that belongs to a bodywork:

<?php
$bodyworkModel->getOne(1)->detachAll();

This will work for both the One To One and the Belongs To.

Delete

In our example we can delete a car very easily.

<?php
$carModel->deleteById(1);
// Deletes the car object, not the relationships with it.

to delete an array of cars we can use the deleteBy()

<?php
$carModel->deleteBy([1, 2, 3, 4, 5]);
// Deletes the cars with the id 1 to 5.

Error

You can use the deleteAll() function but this is not recommended. It will delete all the cars we have. only use it if needen other wise use deleteBy() or deleteById()