Skip to main content
Version: Next

One to One

One to One (Polymorphic)

Collection Structure

A one-to-one polymorphic relation is similar to a typical one-to-one relation; however, the child model can belong to more than one type of model using a single association. For example, a blog Post and a User may share a polymorphic relation to an Image model. Using a one-to-one polymorphic relation allows you to have a single collection of unique images that may be associated with posts and users. First, let's examine the collection structure:

posts
_id - ObjectId
name - string

users
_id - ObjectId
name - string

images
_id - ObjectId
url - string
imageableId - ObjectId
imageableType - string

Note the imageableId and imageableType keys on the images collection. The imageableId column will contain the ID value of the post or user, while the imageableType column will contain the class name of the parent model. The imageableType column is used by Mongoloquent to determine which "type" of parent model to return when accessing the imageable relation. In this case, the column would contain either Post or User.

Model Structure

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

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

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

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

static image() {
return this.morphOne(Image, "imageable");
}
}
// User.js
import { Mongoloquent } from "mongoloquent";
import Image from "./yourPath/Image";

class User extends Mongoloquent {
static collection = "users";
static softDelete = true;
static timestamps = true;

static image() {
return this.morphOne(Image, "imageable");
}
}

Retrieving the Relationship

Once your database collection and models are defined, you may access the relationships via your models. For example, to retrieve the image for a post, we can access the image dynamic relationship property:

import Post from "./yourPath/Post";

const post = await Post.with("image").find("09ab7e3d05d58a1ad250dd80");

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

const video = await User.with("image").find("77bb7e3d05d58a1ad250dd80");

// 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("image", {
select: ["url"],
}).find("09ab7e3d05d58a1ad250dd80");

// with exclude keys
await Post.with("image", {
exclude: ["url"],
}).find("09ab7e3d05d58a1ad250dd80");

Support us

Mongoloquent is an MIT-licensed open source project. It can grow thanks to the support by these awesome people. If you'd like to join them, please read more here.

Sponsors

_

Partners