Bruce Gust
asked on
Is this explanation of Discriminators correct?
Here's my question:
If I attempt to add two notes without refreshing the page, I get an error that looks like this:
Here's my Activity.js with the discriminator key:
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/remin der
...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/remin der" comment?
If I attempt to add two notes without refreshing the page, I get an error that looks like this:
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/remin
...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/remin
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Here's my company.js service:
Open in new window
Look at line #912. What's happening there and why is it throwing an error?I can make my problem go away completely simply be eliminating line #78 on my Activity.js schema: { discriminatorKey: 'type' }
...but why does the problem go away? I don't want to just kill some code without understanding what's happening and what I can do differently.
Thanks!