KeystoneJS plural option not working in AdminUI - node.js

Even if i set the plural option in the list when defining the model,
in the Admin UI it does not show up, it keeps showing the default trailing 's'.
my model:
var keystone = require('keystone');
var Types = keystone.Field.Types;
var Pollo = new keystone.List('Pollo', {
map:{ name: 'nome',},
autokey:{path:'slug', from: 'nome', unique: true},
plural: 'polli'
});
so in the Admin UI i see "pollos" instead of "polli"

In your keystone.List('Pollo', { ... }) options, you need to also add label and singular options in addition to plural.

Related

what is the difference between these 2 mongoose schemas while exporting them?

Below is the schema for one user profile in my project.
var agencyProfile = mongoose.Schema({
name: {
type: String
},
user: {
type: mongoose.Schema.ObjectId,
ref: "users"
}
})
I would like to know what is the difference between these 2 exported schemas?
module.exports = mongoose.model('agencyProfile', agencyProfile);
vs
module.exports = mongoose.model('agencyProfile', agencyProfile, "agencyProfile");
The third argument basically allows you to change the collection name (which is inferred from the model-name by default) to something else. From the documentation:
When no collection argument is passed, Mongoose uses the model name.
If you don't like this behavior, either pass a collection name, use
mongoose.pluralize(), or set your schemas collection name option.
In your case, it does not make any difference as the collection name matches the model name agencyProfile.

Storing form data in MongoDB (Design Question)

Trying to design a Form Entry web app and i've rarely used MongoDB before.
Wondering if this is the best practice for storing form (document) data inside a collection.
const mongoose = require('mongoose');
// Create Schema and Model
const documentSchema = mongoose.Schema({
nps: [{ // New Promotion Submission
documentId: Number,
orgid: Number,
documentFields: [{ // Form Fields
id: Number,
dateTimeSubmitted: Date,
title: String,
productDescription: String,
productUnitSize: Number,
productCartonQty: Number
}]
}]
})
const documents = mongoose.model('documents', documentSchema);
module.exports = documents;
This is absolutely fine design, couple of things to look at:
Make sure you introduce validation on your schema fields, mirror the same validation pattern on the frontend form fields also.
Be consistent with your naming: if you use camelCase in documentId make sure to also origId
Convention says you name a model in singular form, i.e. "Document" not "documents".
If you're going to re-use the documentFields schema anywhere else in other models, make sure to store it as a separate schema and import as needed.

KeystoneJS: site-wide configuration variables in database

When creating a site with KeystoneJS, how might I add some site-wide configuration variables that are stored in the database - that can preferably be manipulated via the admin - in the vein of Craft CMS's 'globals'?
I can't find anything in the Keystone database documentation about this, and would prefer not to use a singleton with a Keystone list (e.g. by implementing a list that has only one item) if at all possible.
I've just had a chat with one of the Keystone developers about this. It's been widely discussed on ProductPains, and as it turns out, having a singleton with a list is currently (as of 0.3.x) the only way to do this:
Define a new model in e.g. models/Configuration.js:
const keystone = require('keystone');
const Types = keystone.Field.Types;
const Configuration = new keystone.List('Configuration', {
nocreate: true,
nodelete: true,
label: 'Configuration',
path: 'configuration',
});
Configuration.add({
siteName: { type: String },
siteDescription: { type: Types.Textarea },
});
Configuration.defaultColumns = 'siteName, siteDescription';
Configuration.register();
Add an update e.g. updates/0.0.2-configuration.js:
exports.create = {
Configuration: [
{ 'siteName': 'My site', 'siteDescription': 'TODO' }
]
};

Mongoose/ MongoDB Database Design

I always have a certain fixed structure in my model (GroupName) and a dynamic part of 1-x (Members).
Group1
GroupName
Member 1
Member 2
Group2
GroupName
Member 1
Group3
GroupName
Member 1
Member 2
Member 3
Is it better to use two tables and connect them later via ids like this:
Groups:
Group1
GroupName
GroupId
Group2
GroupName
GroupId
Members:
Member 1
GroupId
Member 2
GroupId
or to use Schema.Types.Mixed(or anything else)? And how to do it in the second way?
I will always use them in combination later. From a gut feeling I would choose the first method:
http://blog.mongolab.com/2013/04/thinking-about-arrays-in-mongodb/
EDIT:
But even on the second method I have the issue, that one member can belong to multiple groups and I don't want to store him twice. The groups are unique and do only exist once.
But I'm new to MongoDb so I want to learn what's the best option and why.
EDIT II:
I have choosen two divide it into two docs. Is this implementation of the Schemas than correct like this:
var mongoose = require('mongoose');
// define the schema for group model
var groupSchema = mongoose.Schema({
href: {
type: String,
required: true,
unique: true
},
title: String,
members: [id: Schema.Types.ObjectId, name: String]
});
// create the model for users and expose it to our app
module.exports = mongoose.model('group', groupSchema);
&&
var mongoose = require('mongoose');
// define the schema for member model
var memberSchema = mongoose.Schema({
id: {
type:Schema.Types.ObjectId,
required: true,
unique: true
},
amount: String,
name: String
});
// create the model for users and expose it to our app
module.exports = mongoose.model('member', memberSchema);
There is an excellent post on the MongoDB blog which tells us about the various ways a schema can be designed based on the model relationships.
I believe the best schema for you would be to make use of embedded arrays with the member IDs.
//Group
{
_id: '1234',
name: 'some group',
members : [
'abcd',
'efgh'
]
}
EDIT
There is a correction needed in the schema:
// define the schema for group model
var groupSchema = mongoose.Schema({
href: {
type: String,
required: true,
unique: true
},
title: String,
members: [{id: Schema.Types.ObjectId, name: String}] //Needs to be enclosed with braces
});
// create the model for users and expose it to our app
module.exports = mongoose.model('group', groupSchema);
I don't know what your documents contains and if members are a growing array - for example Group1 can have 1-n members in any given moment . if this is the case you should go with option 2: try something like:
{gId: 1, mId: 5}
That is a design best suited for Social graph. Your Group documents will have a fixed size which is good for memory and you can easily get all the members of a group (just don't forget to index gId and mId)
If for each group there is a fixed number of members (or not growing and shrinking to much) then go with option 1
There is a great post by mongoDb team (and also src code) that talks about design.
Socialite

Constant property value in mongoose schema

I have schema where a property always equals 1. I have found a solution, but I don't like it:
var schema = new Schema({
a: Number
});
schema.pre('save', function(){
this.a = 1;
});
Can you please tell me if there is better way to do this? For example:
var schema = new Schema({
a: 1
});
How about using a default value, does it achieve what you want ?
var schema = new Schema({
a: {type: Number, default: 1}
});
If you want to force it, the pre version is the best option.
Another way to achieve this is to use a virtual property. Virtuals are document properties that you can get and set but that do not get persisted to MongoDB. Instead you can specify a getter function that get's called every time you access the a property:
schema.virtual('a').get(function () {
return 1;
});
Now every document of schema will have a property a that equals 1. Note however that because virtuals don't get persisted you are not able to query for them.
Store constants as model properties.
var mySchema = new Schema({
// ...
});
var myModel = mongoose.model('MyModel', mySchema);
myModel.a = 1;
Maybe too late, but for the future, you could use default value with a custom setter that always returns the old value, something like ...
var schema = new Schema({
a: {
type: Number,
default: 1,
set(value) {
return this.a;
},
}
});
The default option will initialize the field and the custom setter will ignore any new value and always reset the field to its previous value (that you set with default).

Resources