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.