Veldora's ActiveRecord ORM supports intuitive relationships between database tables. Relations allow you to define connections directly inside model classes and traverse them cleanly without writing complex JOIN queries.
Supported Relationship Types
| Relationship | Method | Example Use Case |
|---|---|---|
| One-to-One | $this->hasOne(Profile::class) | A User has one Profile |
| One-to-Many | $this->hasMany(Post::class) | An Author has many Posts |
| Inverse One-to-Many | $this->belongsTo(User::class) | A Post belongs to an Author |
| Many-to-Many | $this->belongsToMany(Role::class, 'role_user') | A User has many Roles via a pivot table |
| Has-One-Through | $this->hasOneThrough(History::class, User::class) | A Supplier has one History through a User |
| Has-Many-Through | $this->hasManyThrough(Post::class, User::class) | A Country has many Posts through its Users |
| Polymorphic One-to-One | $this->morphOne(Image::class, 'imageable') | A User or Post has one Image |
| Polymorphic One-to-Many | $this->morphMany(Comment::class, 'commentable') | A Post or Video has many Comments |
| Polymorphic Many-to-Many | $this->morphToMany(Tag::class, 'taggable') | A Post or Video has many Tags via shared pivot |
| Polymorphic Inverse | $this->morphTo('commentable') | A Comment resolves back to Post or Video |
| Polymorphic Many Inverse | $this->morphedByMany(Post::class, 'taggable') | A Tag retrieves all tagged Posts or Videos |
Defining Standard Relationships
app/Models/Post.php
PHP
namespace App\Models;
use Veldora\Framework\Database\Model;
use Veldora\Framework\Database\Relations\BelongsTo;
use Veldora\Framework\Database\Relations\HasMany;
use Veldora\Framework\Database\Relations\HasOne;
use Veldora\Framework\Database\Relations\BelongsToMany;
use Veldora\Framework\Database\Relations\HasOneThrough;
class User extends Model
{
// One-to-One
public function profile(): HasOne
{
return $this->hasOne(Profile::class, 'user_id');
}
// One-to-Many
public function posts(): HasMany
{
return $this->hasMany(Post::class, 'user_id');
}
// Many-to-Many via pivot table
public function roles(): BelongsToMany
{
return $this->belongsToMany(Role::class, 'role_user', 'user_id', 'role_id');
}
}
class Supplier extends Model
{
// Has-One-Through (Supplier -> User -> History)
public function userHistory(): HasOneThrough
{
return $this->hasOneThrough(History::class, User::class, 'supplier_id', 'user_id');
}
}Defining Polymorphic Relationships
Polymorphic relations allow a single model to belong to more than one other type of model on a single association:
app/Models/Post.php
PHP
namespace App\Models;
use Veldora\Framework\Database\Model;
use Veldora\Framework\Database\Relations\MorphTo;
use Veldora\Framework\Database\Relations\MorphOne;
use Veldora\Framework\Database\Relations\MorphMany;
use Veldora\Framework\Database\Relations\MorphToMany;
use Veldora\Framework\Database\Relations\MorphedByMany;
class Post extends Model
{
// Polymorphic One-to-One
public function headerImage(): MorphOne
{
return $this->morphOne(Image::class, 'imageable');
}
// Polymorphic One-to-Many
public function comments(): MorphMany
{
return $this->morphMany(Comment::class, 'commentable');
}
// Polymorphic Many-to-Many
public function tags(): MorphToMany
{
return $this->morphToMany(Tag::class, 'taggable');
}
}
class Comment extends Model
{
// Polymorphic Inverse (resolves owner: Post, Video, Podcast, etc.)
public function commentable(): MorphTo
{
return $this->morphTo('commentable');
}
}
class Tag extends Model
{
// Inverse Polymorphic Many-to-Many
public function posts(): MorphedByMany
{
return $this->morphedByMany(Post::class, 'taggable');
}
}Querying and Creating Across Relations
Access related models as dynamic properties or chain queries directly:
example.php
PHP
$user = User::find(1);
// Access relations as dynamic properties
$posts = $user->posts;
// Query builder chaining via relation proxy
$published = $user->posts()->where('is_published', '=', 1)->get();
// Create related polymorphic records directly
$post = Post::find(10);
$comment = $post->comments()->create([
'body' => 'Great overview of Veldora relationships!',
]);
// Attach / Detach / Sync on polymorphic and pivot relations
$post->tags()->attach([1, 2]);
$post->tags()->detach(1);
$post->tags()->sync([2, 3, 5]);