scyllinx
Version:
A modern TypeScript ORM for ScyllaDB and SQL databases with Laravel-inspired syntax
165 lines (164 loc) • 5.4 kB
TypeScript
import type { InferAttributes, Model } from "@/model/Model";
import { QueryBuilder } from "@/query/QueryBuilder";
import { Relationship } from "./Relationship";
/**
* Represents a polymorphic belongs-to relationship.
* Allows a model to belong to multiple different parent model types.
* The inverse of MorphOne and MorphMany relationships.
*
* @template T - The child model type (the one with morph columns)
* @template R - The parent model type (can be multiple types)
*
* @example
*
* // In Comment model
* commentable(): MorphTo<Comment, User | Post> {
* return new MorphTo(this, 'commentable_type', 'commentable_id', 'id')
* .registerModel('user', User)
* .registerModel('post', Post);
* }
*
* // Usage
* const comment = await Comment.find(1);
* const parent = await comment.commentable().getResults();
*
* if (parent instanceof User) {
* console.log(`Comment on user: ${parent.name}`);
* } else if (parent instanceof Post) {
* console.log(`Comment on post: ${parent.title}`);
* }
*
*/
export declare class MorphTo<T extends Model<any>, R extends Model<any>> extends Relationship<T, R> {
protected morphType: string;
protected morphId: string;
protected models: Map<string, new () => R>;
/**
* Creates a new MorphTo relationship instance.
*
* @param parent - Child model instance (the one with morph columns)
* @param morphType - Column name storing the parent model type
* @param morphId - Column name storing the parent model ID
* @param localKey - Local key on parent models (usually primary key)
*
* @example
*
* // Comment belongs to User or Post polymorphically
* new MorphTo(
* this, // Comment instance
* 'commentable_type', // stores 'user' or 'post'
* 'commentable_id', // stores the parent ID
* 'id' // parent's primary key
* );
*
*/
constructor(parent: T, morphType: string, morphId: string, localKey: string);
/**
* Adds constraints to the relationship query.
* For MorphTo relationships, constraints are applied dynamically based on morph type.
*
* @param query - Query builder to add constraints to
* @returns Query builder (unchanged for MorphTo)
*/
addConstraints(query: QueryBuilder<R, InferAttributes<R>>): QueryBuilder<R, InferAttributes<R>>;
/**
* Gets the relationship results.
* Determines the parent model type from morph type column and queries accordingly.
*
* @returns Promise resolving to parent model or null
*
* @example
*
* const comment = await Comment.find(1);
* const parent = await comment.commentable().getResults();
*
* // Parent could be User, Post, or any registered model type
* if (parent) {
* console.log(`Parent type: ${comment.commentable_type}`);
* console.log(`Parent ID: ${comment.commentable_id}`);
* }
*
*/
getResults(): Promise<R | null>;
/**
* Registers a model class for a specific morph type.
* Required to map morph type strings to actual model classes.
*
* @param type - Morph type string (stored in morph type column)
* @param modelClass - Model constructor for this type
* @returns This relationship instance for method chaining
*
* @example
*
* const morphTo = new MorphTo(this, 'commentable_type', 'commentable_id', 'id')
* .registerModel('user', User)
* .registerModel('post', Post)
* .registerModel('page', Page);
*
*/
registerModel(type: string, modelClass: new () => R): this;
/**
* Associates the child model with a parent model.
* Sets both the morph type and morph ID columns.
*
* @param model - Parent model to associate with
* @returns The child model for method chaining
*
* @example
*
* const comment = new Comment();
* const user = await User.find(1);
*
* comment.commentable().associate(user);
* console.log(comment.commentable_type); // 'user'
* console.log(comment.commentable_id); // user.id
*
* await comment.save();
*
*/
associate(model: R): T;
/**
* Dissociates the child model from its parent.
* Sets both morph type and morph ID columns to null.
*
* @returns The child model for method chaining
*
* @example
*
* const comment = await Comment.find(1);
*
* comment.commentable().dissociate();
* console.log(comment.commentable_type); // null
* console.log(comment.commentable_id); // null
*
* await comment.save();
*
*/
dissociate(): T;
/**
* Gets the morph type value from the child model.
*
* @returns The morph type string or null
*
* @example
*
* const comment = await Comment.find(1);
* const type = comment.commentable().getMorphType();
* console.log(type); // 'user', 'post', etc.
*
*/
getMorphType(): string | null;
/**
* Gets the morph ID value from the child model.
*
* @returns The morph ID value or null
*
* @example
*
* const comment = await Comment.find(1);
* const id = comment.commentable().getMorphId();
* console.log(id); // 123, 456, etc.
*
*/
getMorphId(): any;
}