Skip to main content
Version: v2.x.x

One to Many

One to Many (Polymorphic)

Collection Structure

A one-to-many polymorphic relation is similar to a typical one-to-many relation; however, the child model can belong to more than one type of model using a single association. For example, imagine users of your application can "comment" on posts and videos. Using polymorphic relationships, you may use a single comments collection to contain comments for both posts and videos. First, let's examine the collection structure required to build this relationship:

posts
_id - ObjectId
title - string
body - text

videos
_id - ObjectId
title - string
url - string

comments
_id - ObjectId
body - text
commentableId - ObjectId
commentableType - string

Model Structure

Next, let's examine the model definitions needed to build this relationship:

// Comment.js
import { Mongoloquent } from "mongoloquent";

class Comment extends Mongoloquent {
static collection = "comments";
static softDelete = true;
static timestamps = true;
}
// Post.js
import { Mongoloquent } from "mongoloquent";
import Comment from "./yourPath/Comment";

class Post extends Mongoloquent {
static collection = "posts";
static softDelete = true;
static timestamps = true;

/**
* Get all of the post's comments.
*/
static comments() {
return this.morphMany(Comment, "commentable");
}
}
// Video.js
import { Mongoloquent } from "mongoloquent";
import Comment from "./yourPath/Comment";

class Video extends Mongoloquent {
static collection = "videos";
static softDelete = true;
static timestamps = true;

/**
* Get all of the video's comments.
*/
static comments() {
return this.morphMany(Comment, "commentable");
}
}

Retrieving the Relationship

Once your database collection and models are defined, you may access the relationships via your model's dynamic relationship properties. For example, to access all of the comments for a post, we can use the comments dynamic property:

import Post from "./yourPath/Post";

const post = await Post.with("comments").find("10ab7e3d05d58a1ad250dd90");

// your relationship data can accessed in the data property
console.log(post.data);
import Video from "./yourPath/Video";

const video = await Video.with("comments").find("11bb7e3d05d58a1ad250dd99");

// your relationship data can accessed in the data property
console.log(video.data);

Monggoloquent can also select or exclude certain related model keys

import Post from "./yourPath/Post";

// with select keys
await Post.with("comments", {
select: ["body"]
}).find("56ab7e3d05d58a1ad250dd56");

// with exclude keys
await Post.with("comments", {
exclude: ["body"]
}).find("56ab7e3d05d58a1ad250dd56");
---

---

<Sponsor />