troubleshooting Question

Is this explanation of Discriminators correct?

Avatar of Bruce Gust
Bruce GustFlag for United States of America asked on
JavaScriptNode.js
2 Comments1 Solution44 ViewsLast Modified:
Here's my question:

If I attempt to add two notes without refreshing the page, I get an error that looks like this:

screenshot
Here's my Activity.js with the discriminator key:

const mongoose = require('mongoose');

const { Schema } = mongoose;

const ActivitySchema = new Schema(
  {
    type: {
      type: String,
      required: true,
      enum: [
        'call',
        'visit',
        'reminder',
        'event',
        'Company created',
        'Company updated',
        'Company deleted',
        'Broker info added',
        'Broker info updated',
        'Contact added',
        'Contact updated',
        'Contact deleted',
        'Address added',
        'Address updated',
        'Address deleted',
        'Proposal created',
        'Proposal updated',
        'Converted to company',
        'Target selected',
        'Target ignored',
        'Owner change',
        'Proposal assigned',
        'File attached',
        'File removed',
        'User added',
        'User deleted',
        'Service line added',
        'Service line deleted',
        'Swimlane added',
        'Swimlane removed',
        'Custom Fields Updated',
        'Proposal downloaded',
        'Proposal emailed'
      ]
    },
    company: {
      type: Schema.Types.ObjectId,
      required: true,
      ref: 'Company'
    },
    proposal: {
      type: Schema.Types.ObjectId,
      ref: 'Proposal'
    },
    pipeline: {
      type: Schema.Types.ObjectId, // for tracking activity on each pipeline stage.
      ref: 'PipelineColumn'
    },
    user: {
      type: Schema.Types.ObjectId,
      ref: 'User'
    },
    date: {
      type: Date,
      default: Date.now
    },
    meta: {
      Details: String,
      date: Date,
      notes: String
    },
    account: {
      type: Schema.Types.ObjectId,
      default: () => global._user.account._id
    },
    active: { type: Boolean, default: true }
  },
  { discriminatorKey: 'type' }
);
// removed strict:false and added discriminatorKey for meta.start, meta.end, meta.date fields for type=event/call/note/reminder

module.exports = ActivitySchema;

Based on what I understand about Discriminators, this:

// removed strict:false and added discriminatorKey for meta.start, meta.end, meta.date fields for type=event/call/note/reminder

...is bogus.

Tell me if I'm right...

A Discriminator is what connects two models together. For example, I have a base model where I define several fields as well as a "discriminator key." That "key" is actually another column that will be defined in a different model.

If I have a collection of books, a collection of movies and a collection of tv shows, they all have "titles" and "release dates." They're unique, however, in that each book has an "author," a TV Show has a "season" and a movie has  "director."

I can set up my database in a way where I've got a "base" model that has two columns set aside for "titles" and "release date" and also includes a "discriminator key" called, "itemtype." You can almost think of this as an abstract class in that you'll never directly called the "base" model, although it's present in every one of the other models that you will call.

My "books" model will have a single column called "author." But in reality, the "books" model will be processed as having, not just the "author" column, because it's an extension of the "base" model, it will include all of the other columns referenced in the "base" model as well.  

So, for all intents and purposes, when we go to retrieve the info from the "book" collection (which is based on the "book.js" model), it will look like this:

{
    "_id": {
        "$oid": "unique object ID"
    },
    "itemtype": "Book",
    "author": "Book Author 1",
    "title": "Book Title 1",
    "date_added": {
        "$date": "2018-02-01T00:00:00.000Z"
    },
    "redo": false,
}

What you see in bold is the "discriminator key" established in the "base" model.

Notice in the base.js file, the "discriminator key" is referred to as "itemtype." That's just a place holder. When it's actually rendered, that column will read "author" for books, "director" for movies and "season" for TV shows.

is that explanation correct?

Based on that explanation, when I do a search for "discriminator" in my schemas directory, it shows up one time and one time only and that's in the "Activity.js" schema that you see above.

That seems wrong for two reasons.

First of all, I don't see how the Activity.js schema is serving as a "base" for another model and...

...a Discriminator key is not going be named according to an incoming piece of data. Based on what I understand that key is a unique placeholder and to refer to it using the same name as an incoming value is wrong.

When I remove this:   { discriminatorKey: 'type' }

I can add as many notes as I want to and will not get that error.

But have I compromised something else based on the "// removed strict:false and added discriminatorKey for meta.start, meta.end, meta.date fields for type=event/call/note/reminder" comment?
Join the community to see this answer!
Join our exclusive community to see this answer & millions of others.
Unlock 1 Answer and 2 Comments.
Join the Community
Learn from the best

Network and collaborate with thousands of CTOs, CISOs, and IT Pros rooting for you and your success.

Andrew Hancock - VMware vExpert
See if this solution works for you by signing up for a 7 day free trial.
Unlock 1 Answer and 2 Comments.
Try for 7 days

”The time we save is the biggest benefit of E-E to our team. What could take multiple guys 2 hours or more each to find is accessed in around 15 minutes on Experts Exchange.

-Mike Kapnisakis, Warner Bros