VeldoraDocs

7. Model Relationships

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

RelationshipMethodExample 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]);


Building with AI Assistants?
Copy the Veldora AI Developer Prompt to teach ChatGPT, Claude, Cursor, or Gemini all framework APIs for error-free coding.