इनहेरिटेंस मैपिंग
Weaver ORM supports three inheritance patterns. Choose based on how similar your subclass schemas are and how often you need to query across all types in a single SELECT.
Strategies at a glance
| Strategy | Tables | Best when |
|---|---|---|
| Mapped Superclass | One per concrete subclass | Shared columns, no polymorphic queries |
| Single Table Inheritance (STI) | One shared table | Mostly similar columns, ≤6 subtypes |
| Class Table Inheritance (CTI) | One per class | Very different columns, frequent joins |
Mapped Superclass
A mapped superclass is an abstract PHP class that contributes columns to its subclasses but has no table of its own. Each concrete subclass gets its own table containing the superclass columns plus its own.
Use this when you have common fields (createdAt, updatedAt, createdBy) shared across many unrelated entities, and you do not need polymorphic queries across them.
Pattern
// Abstract PHP class — no Weaver coupling
abstract class TimestampedEntity
{
public function __construct(
protected \DateTimeImmutable $createdAt,
protected ?\DateTimeImmutable $updatedAt,
) {}
public function getCreatedAt(): \DateTimeImmutable { return $this->createdAt; }
public function getUpdatedAt(): ?\DateTimeImmutable { return $this->updatedAt; }
}
Abstract base mapper — defines the shared columns as a reusable method:
abstract class TimestampedEntityMapper extends AbstractMapper
{
protected function timestampColumns(): array
{
return [
ColumnDefinition::datetimeImmutable('created_at')->notNull(),
ColumnDefinition::datetimeImmutable('updated_at')->nullable(),
];
}
}
Concrete subclass mapper — spreads the shared columns:
final class ArticleMapper extends TimestampedEntityMapper
{
public function table(): string { return 'articles'; }
public function schema(): SchemaDefinition
{
return SchemaDefinition::define(
ColumnDefinition::integer('id')->autoIncrement()->unsigned(),
ColumnDefinition::string('title')->notNull(),
ColumnDefinition::text('body')->notNull(),
...$this->timestampColumns(), // spread shared columns
);
}
public function hydrate(array $row): Article
{
return new Article(
id: (int) $row['id'],
title: $row['title'],
body: $row['body'],
createdAt: new \DateTimeImmutable($row['created_at']),
updatedAt: isset($row['updated_at'])
? new \DateTimeImmutable($row['updated_at'])
: null,
);
}
}
Generated SQL for articles:
CREATE TABLE articles (
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
title VARCHAR(255) NOT NULL,
body TEXT NOT NULL,
created_at DATETIME NOT NULL,
updated_at DATETIME NULL,
PRIMARY KEY (id)
);