Relations

The ORM supports relationships between models using the hasRelation() method. This method retrieves related models based on a foreign key and primary key relationship between two tables.

In relational databases, relationships are usually established by storing the primary key of one table inside another table as a foreign key. The hasRelation() method simply uses this principle to automatically retrieve related records by matching those keys.

For example, if a User model has many Post models, you can define the relationship in the User model as follows:


<?php

namespace App\Models;

use SigmaPHP\Core\Models\BaseModel;

class User extends BaseModel
{
    public function posts()
    {
        return $this->hasRelation(
            Post::class,
            'user_id',
            'id'
        );
    }
}
    

In this example, the ORM will retrieve all records from the posts table where the user_id column matches the current user's id. Internally, this is equivalent to a query similar to:


SELECT * FROM posts WHERE user_id = {user.id}
    

The hasRelation() method accepts three parameters:

$model The related model class
$foreignKey The foreign key in the related table
$localKey The local key used to match the foreign key

You can then retrieve the related models by calling the relationship method.


<?php

$user = $userModel->findBy('name', 'test');

$posts = $user->posts();

In this case, the relationship represents a one-to-many association: one user can have many posts.

For the reverse relation, which in our example means retrieving the author of a post, the same hasRelation() method can be used again. However, this time the relationship is reversed, so the $localKey and $foreignKey must be swapped.

This works because the ORM simply compares the two values. When retrieving posts from a user, we match:


posts.user_id = users.id
    

But when retrieving the user from a post, the comparison becomes:


users.id = posts.user_id
    

Since the comparison direction is reversed, the keys must also be reversed when calling hasRelation().


<?php

namespace App\Models;

use SigmaPHP\Core\Models\BaseModel;

class Product extends BaseModel
{
    public function author()
    {
        return $this->hasRelation(
            User::class,
            'id',
            'user_id',
        );
    }
}
    

In this case, the ORM will retrieve the User whose id matches the user_id stored in the current post record.

Using the same method for both directions keeps the API simple while still allowing you to define different types of relationships depending on how the keys are mapped between models.

Back to top