I got this SimpleSchema for a collection in my meteor-app
Collection.attachSchema(new SimpleSchema({
title: { type: String },
slug: { type: String, unique: true },
language: { type: String, defaultValue: "en" },
'category.element': { type: String, optional: true }
}));
And I try to insert this JSON-data, but I get insert failed: Error: Category must be an object at getErrorObject
{
"_id" : "25uAB4TfeSfwAFRgv",
"title" : "Test 123",
"slug" : "test_123",
"language" : "en",
"category" : [
{
"element" : "Anything"
}
]
}
What is wrong with my JSON-data? Or what's wrong with my SimpleSchema. I can change both of them to match the best way.
You need to first declare the object, like,
Collection.attachSchema(new SimpleSchema({
...,
....,
category: {type: [Object], optional: true}
}));
After that you can extend/define object field(s) like,
Collection.attachSchema(new SimpleSchema({
....,
....,
category: {type: [Object]},
'category.$.element': {type: String}
}));
use '$' if its a Array Object ([Object]), If only object then then do not use '$'.
If you do not sure about Object Structure, use another parameter blackbox:true
like,
category: {type: [Object], blackbox: true}
The simplest solution is to define category as an array of objects in your schema:
Collection.attachSchema(new SimpleSchema({
title: { type: String },
slug: { type: String, unique: true },
language: { type: String, defaultValue: "en" },
category: { type: [Object], optional: true }
}));
This will get you unstuck.
If you want to be more specific about the contents of category then you can define a sub-schema for category. For example:
CategorySchema = new SimpleSchema({
element: { type: String }
});
Collection.attachSchema(new SimpleSchema({
title: { type: String },
slug: { type: String, unique: true },
language: { type: String, defaultValue: "en" },
category: { type: [CategorySchema], optional: true }
}));
Related
Trying to work with sequalize association ( belongsTo and hasMany() ) but when i tries to query findAll with include the Model which was associated it fails by saying Models are not associated.
User Model
const {DATE, STRING, INTEGER} = require("sequelize");
const {USER} = require("../config/db.config");
module.exports = (sequelize, Sequelize) => {
const User = sequelize.define("Users", {
id: {
primaryKey: true, type: INTEGER, required: true, autoIncrement: true
}, phoneNumber: {
type: STRING, required: true, unique: true
}, firstname: {
type: STRING, required: true
}, middlename: {
type: STRING, required: false
}, region: {
type: STRING, required: true
}, district: {
type: STRING, required: true
}, street: {
type: STRING, required: true
}, lastname: {
type: STRING, required: true,
}, 'type': {
type: STRING, required: true,
}, email: {
type: STRING, required: true, unique: true
}, status: {
type: Sequelize.ENUM("ACTIVE", "NOT-ACTIVE", "SUSPENDED"), defaultValue: "NOT-ACTIVE",
}, createdAt: {
type: DATE,
}, updatedAt: {
type: DATE,
}
});
User.associate = function (models) {
User.hasMany(models.Students, {foreignKey: 'userId', as: 'user'});
}
return User;
};
Student Model
const {DATE, STRING, INTEGER} = require("sequelize");
module.exports = (sequelize, Sequelize) => {
const Student = sequelize.define("Students",
{
id: {
primaryKey: true, type: STRING, required: true
}, userId: {
type: INTEGER, required: true,
}, status: {
type: Sequelize.ENUM("ACTIVE", "NOT-ACTIVE", "SUSPENDED"), defaultValue: "NOT-ACTIVE",
},
level: {
type: STRING, required: true,
}, createdAt: {
type: DATE,
}, updatedAt: {
type: DATE,
}
});
Student.associate = function (models) {
Student.belongsTo(models.Users, {foreignKey: 'userId', as: 'user'})
Student.belongsToMany(models.Classes, {through: 'StudentClass',})
}
return Student;
};
I have tried to query them by using the bellow function but i got nothing
function getAllStudents() {
Student.findAll({include: [{model: User, as: 'user', required: true}]}).then(value => {
console.log(value)
return value;
}).catch(reason => {
console.error(reason)
})
}
But i get the following
Result i get
It's weird for Mongoose to say that because I'm pretty sure I have the thing.
This is my Mongoose model:
var Job = mongoose.model('Job', new Schema({
_creator: {
type: mongoose.Schema.Types.ObjectId,
required: true
},
companyName: {
type: String,
required: true,
trim: true
},
position: {
type: String,
required: true,
trim: true
},
isCurrent: {
type: Boolean
// required: true
},
startedDate: {
type: Date,
required: true
},
endDate: {
type: Date
},
descriptions: [{
description: {
type: String,
required: true
},
skills: [{
skillId: {
type: mongoose.Schema.Types.ObjectId,
required: true
},
skillName: {
type: String,
required: true
}
}]
}]
}));
And here's the dummy data I'm trying to send to my server, printed right before posting:
Yet it tells me that it requires the path description which is already included in the job object above:
Super confused. Any help appreciated!
I'm bangin' my head against the wall in the last hours, and I can't figure out a solution to my problem. In my sails models, I have 2 one-to-many associations. 'A' model can have many 'B', and 'B' model can have many 'C'. In my controller, when I do a.find().populate('b') (...) it returns me the entire collection of A model, but populate each entry of A model with only one B, which doesn't match the current dataset I have in my database(mysql). And doesn't populate the C entries in the B model. In other words, I'm trying to achieve something like nested population.
It's something wrong with the Controller code, right? How can I make this work?
Thanks in advance!
EDIT:
Company.js
module.exports = {
identity: 'company',
attributes: {
name: {
type: 'string',
required: true
},
address: {
type: 'string',
required: true
},
zip_code: {
type: 'string',
required: true
},
city: {
type: 'string',
required: true
},
nif: {
type: 'integer',
required: true,
minLength: 9
},
country: {
type: 'string',
required: true
},
phone_number: {
type: 'string',
required: true
},
email: {
type: 'email',
required: true
},
facilities: {
collection: 'facility',
references: 'facility',
on: 'id',
via: 'company'
}
}
};
Facility.js
module.exports = {
identity: 'facility',
attributes: {
company: {
columnName: 'id_company',
model: 'company'
},
warehouses: {
collection: 'warehouse',
references: 'warehouse',
on: 'id',
via: 'facility'
},
name: {
type: 'string',
required: true
},
address: {
type: 'string',
required: true
},
zip_code: {
type: 'string',
required: true
},
city: {
type: 'string',
required: true
},
country: {
type: 'string',
required: true
},
phone_number: {
type: 'string',
},
email: {
type: 'email',
},
longitude: {
type: 'float',
},
latitude: {
type: 'float'
}
}
};
Warehouse.js
module.exports = {
identity: 'warehouse',
attributes: {
facility: {
columnName: 'id_facility',
model: 'facility',
},
name: {
type: 'string',
required: true
},
longitude: {
type: 'float',
},
latitude: {
type: 'float'
}
}
};
MainController's relevant code:
companies: function(req, res) {
company.find().populate('facilities').exec(function(err, comp){
var error = '';
if(err){
error = 'Unable to retrieve the requested information. Try again later and, if the problem persists, contact the platform administrator.';
} else if(!comp[0]) {
error = 'There\'s no company data inserted.';
}
// (...)
});
},
You should remove the references and on from your models.
Regarding nested population, just like I said in the comment, Waterline does not currently support it. You could check Waterline2 which, as they say, offers the possibility of nested populating, but is not recommended for production.
Otherwise you could check this out: Sails.js populate nested associations
I am trying to create a classic Articles/Categories association with mongoose.
Everything works fine, but since I am trying to expose the query results as JSON, I get a Converting circular structure to JSON error.
I know the issue is related in cross referencing models, but I don't know how to solve this.
Here are my model schemas.
var ArticleSchema = new Schema({
created: {
type: Date,
default: Date.now
},
title: {
type: String,
default: '',
trim: true
},
content: {
type: String,
default: '',
trim: true
},
user: {
type: Schema.ObjectId,
ref: 'User'
},
categories: [{
type: Schema.ObjectId,
ref: 'Category'
}]
});
ArticleSchema.statics.load = function(id, cb) {
this.findOne({
_id: id
}).populate('user', 'name username').populate('categories', 'title').exec(cb);
};
/**
* Category Schema
*/
var CategorySchema = new Schema({
created: {
type: Date,
default: Date.now
},
title: {
type: String,
default: '',
trim: true
},
user: {
type: Schema.ObjectId,
ref: 'User'
}
},
{
toObject: { virtuals: true },
toJSON: { virtuals: true }
});
/**
* Virtual Schema
*/
var articles = CategorySchema.virtual('articles');
articles.get(function () {
return Article.find({categories : { $eq: this }});
});
Seems to be like you have circular references, this mean that the json you create is calling it self in somere.. Im not sure if this line could be the problem:
articles.get(function () {
return Article.find({categories : { $eq: this }});
});
why dont you try with a hardcore value in $eq ??
I have a given database with long, cumbersome columnnames. Isn't there any way to map the tablenames to shorter and more descriptive propertyNames in the model ?
something like
var Employee = sql.define('Employee', {
id : {type : Sequelize.INTEGER , primaryKey: true, map : "veryLongNameForJustTheId"}
},{
tableName: 'cumbersomeTableName',
timestamps: false
});;
id : {
field: 'some_long_name_that_is_terrible_thanks_dba_guy',
type : Sequelize.INTEGER ,
primaryKey: true
}
Specify a 'field' attribute ... Like that ^
You can specify a table name by supplying the name as the first parameter to the define() call. For example:
var User = sequelize.define(
'a_long_cumbersone_users_table_name',
{
id: {
type: Sequelize.INTEGER,
primaryKey: true
},
name: {
type: Sequelize.STRING
},
email: {
type: Sequelize.STRING
},
password: {
type: Sequelize.STRING
},
rememberToken: {
type: Sequelize.STRING,
field: 'remember_token'
}
},
{
underscored: true,
timestamps: true,
createdAt: 'created_at',
updatedAt: 'updated_at'
}
);
So far the best solution I found to do this is to use getters and setters.
They will - however - not affect results in object.values or object.toJSON(). You'll need your own serialization methods if you want to use these.