I'm creating a model that needs some validations, but the validations handle an error when I input the correct or wrong data.
What is the right way to configure model validations?
My model is:
return sequelize.define('books', {
id : { type: DataTypes.BIGINT , primaryKey:true, autoIncrement:true },
isbn_10 : { type: DataTypes.BIGINT , allowNull: false,
validate: {
min:10,
max:10
}
},
title : { type: DataTypes.STRING , allowNull: false,
validate: {
isNumeric:true,
min:2,
max:255
}
}, { underscored :true, freezeTableName:true});
And I'm validation on this way:
models.Book.create(req.body)
.success(function(book) { console.log(book); res.render('books/create', { books:models.Book }); })
.error(function(errors) {
console.log(errors);
});
The form input data is:
{ Book:
{ isbn_10: '123123131',
title: '',
cadastrar: 'Submit Query' }}
Thanks.
The problem was solved, I update the sequelize version form 2.0.0.alpha.0 to 2.0.0.dev11 and the validations start to work again.
Thanks.
Related
Forgive my limited knowledge im about a week into using Sequelize,
Models.PlannerModel.Builds.findAll({
raw: true,
where: {
ProposedDelivery: { [Op.gt]: moment().format("YYYY-MM-DD") },
description: { [Op.ne]: null },
description: { [Op.ne]: " " },
description: { [Op.not]: null },
},
include: [
{
model: Models.PlannerModel.Unit,
required: true
},
],
the result from the above is as you would expect except all the keys for the fields in the includes are as strings so referencing them in my Pug template/class has to be done with brackets
overall not the end of the world just wondering if im doing something wrong ?
Cheers!
Turn off raw to get nested model objects and also to get plain objects use get({ plain: true}) for each returned model instance:
const builds = await Models.PlannerModel.Builds.findAll({
where: {
ProposedDelivery: { [Op.gt]: moment().format("YYYY-MM-DD") },
[Op.and]: [{
description: { [Op.ne]: null },
}, {
description: { [Op.ne]: " " },
}, {
description: { [Op.not]: null },
}
]
},
include: [
{
model: Models.PlannerModel.Unit,
required: true
},
]
})
const plainBuilds = builds.map(x => x.get({ plain: true }))
Please pay attention that I changed conditions with description. In your version of conditions only the last one will work because JS saves only the last key if there are several same keys in the same object.
I've breaking my head over this sequelize to get the products questions and also to include its answers as well
const ProductQuestions = sequelize.define('product_questions', {
user: {
type: Sequelize.BIGINT
},
product: {
type: Sequelize.BIGINT
},
question: {
type: Sequelize.TEXT
}
});
ProductQuestions.associate = function(models) {
ProductQuestion.hasMany(models.product_answers,{
foreignKey: 'question',
as: 'questionId'
});
}
const ProductAnswer = sequelize.define('product_answers', {
question: {
type: Sequelize.BIGINT,
field: 'questionId'
},
answer: {
type: Sequelize.TEXT
},
user: {
type: Sequelize.BIGINT,
field: 'userId'
}
});
ProductQuestiosn.findAll({include: ['product_answers']});
for some reason when I that, the columns is wrong when the query runs
SELECT
"product_questions".*,
"product_answers"."id" AS "product_answers.id",
"product_answers"."questionId" AS "product_answers.questionId",
"product_answers"."answer" AS "product_answers.answer",
"product_answers"."userId" AS "product_answers.user",
"product_answers"."productQuestionId" AS "product_answers.productQuestionId"
FROM (
SELECT
"product_questions"."id",
"product_questions"."productId" AS "product",
"product_questions"."question",
"product_questions"."userId" AS "user",
FROM
"product_questions" AS "product_questions")
AS "product_questions"
LEFT OUTER JOIN "product_answers" AS "product_answers"
ON "product_questions"."id" = "product_answers"."productQuestionId"
not sure why is
ON "product_questions"."id" = "product_answers"."productQuestionId"
when it should be
ON "product_questions"."id" = "product_answers"."questionId"
thank you for your help
so i figured it out!
so it appears that I have to name my columns properly
for the product_answers table in my postgres database, I had the column questionId but it should be named productQuestionId. I guess it's for naming convention, i can't just name the foreign key the way i want.
I can't get this very simple virtual column to work (surnameName). It is not returned in query results, but it does not throw any error either.
My model (I removed irrelevant fields):
const Person = connectionPool.define('person', {
ID: {
type: Sequelize.INTEGER,
autoIncrement: true,
allowNull: false,
primaryKey: true
},
name: Sequelize.STRING,
surname: Sequelize.STRING,
surnameName: {
type: Sequelize.VIRTUAL(Sequelize.STRING, ['surname', 'name']),
get() {
return this.getDataValue('surname') + ' ' + this.getDataValue('name');
}
}
});
This is how I query the model:
const cfg = {
where: {},
limit: 10,
raw: false, // tried with and without this line
attributes: ['surnameName']
}
models.Person.findAll(cfg)
.then(results => {
console.log(results[0]);
})
And this is what I get in the console log:
person {
dataValues: { surname: 'Baggins', name: 'Frodo' }, // all other fields are autoexcluded by Sequelize
...
_options:
{ isNewRecord: false,
_schema: null,
_schemaDelimiter: '',
raw: true, // is true even if I set 'raw' to false in findAll options
attributes: [ 'surnameName', 'surname', 'name' ] // <= surnameName is there!
}
}
Virtual column is not returned in the results, however the logged instance shows that the internal _options.attributes array does contain the field, so Sequelize somehow acknowledges that it should be added. I tried explicitly turning raw=false, as I read that raw excludes virtual columns, but it has no effect. The results are definitely not raw.
What can be wrong here? Any help will be appreciated!
It is possible to hide properties javascript object. Here is an example
function Person(fName, lName) {
this.fName = fName;
this.lName = lName;
Object.defineProperties(this, {
fullName: {
get : function () {
return this.fName + " " + this.lName;
}
}
});
}
const ratul = new Person("Ratul", "sharker");
console.log(ratul);
console.log(ratul.fullName);
Look closely that console.log(ratul) does not print fullName, but fullName is sitting here, returning it's value seen in console.log(ratul.fullName).
Similar thing can be found in this answer.
operation_sav model is defined as follows:
operation_sav.js
module.exports = function(sequelize, DataTypes) {
var operation_sav = sequelize.define(
"operation_sav",
{
id: {
type: DataTypes.INTEGER,
primaryKey: true,
allowNull: false,
autoIncrement: true,
unique: true
},
nom_operation: DataTypes.STRING,
status: {
type: DataTypes.ENUM(
"en_cours_livraison",
"en_reparation",
"repare",
"expedie"
),
defaultValue: "en_cours_livraison"
},
num_serie: DataTypes.STRING,
address_mac: DataTypes.STRING,
sous_garantie: DataTypes.BOOLEAN,
description: DataTypes.STRING,
adminId: DataTypes.INTEGER,
produitId: DataTypes.INTEGER,
status: {
type: DataTypes.ENUM(
"produit_recu",
"en_livraison",
"en_reparation",
"repare",
"en_expedition",
"expedie",
"annule"
),
defaultValue: "produit_recu"
}
},
{ timestamps: true }
);
return operation_sav;
};
Notice there's an external foreign key adminId
The relationship between table Admin and table Operation_sav is defined as follows:
/** admin Has Many operation_sav*/
model.operation_sav.belongsTo(model.admin, {
foreignKeyConstraint: true,
onDelete: "cascade"
});
model.admin.hasMany(model.operation_sav, {
foreignKeyConstraint: true,
onDelete: "cascade"
});
This is the function that creates a row inside the Operation_sav table:
var createSavOperation = function(operationInformation) {
return models.operation_sav.create(operationInformation);
};
I have used it to create this row:
{
"id": 4,
"nom_operation": "RĂ©partion viwone plus",
"status": "produit_recu",
"num_serie": "5525ggffdd",
"address_mac": "ff:ff:ff:ff:ff",
"sous_garantie": true,
"description": "Panne bouton droit",
"adminId": 10,
"produitId": 6,
"updatedAt": "2020-02-27T09:22:47.430Z",
"createdAt": "2020-02-27T09:22:47.430Z"
}
Notice that adminId is 10 and operation_savId is 4. So I try to see if the whole association has worked properly by running this code:
models.operation_sav.findByPk(4).then(operation_sav => {
admin = models.admin.findByPk(10);
admin.hasOperation_sav(operation_sav);
});
However, I get this error:
Unhandled rejection TypeError: admin.hasOperation_sav is not a
function
Is this because I have manually written the adminId value when creating that operation_sav row?
EDIT 1: When I added this console.log line:
admin = models.admin.findByPk(10);
console.log(admin instanceof models.admin); // false!!
admin.hasoperation_sav(operation_sav);
I get false which doesn't make any sense but it kindof explains why sequelize is not throwing the admin.hasoperation_sav is not a function error..
EDIT 2: I have fixed EDIT 1 like this:
models.admin.findByPk(10).then(adminFound => {
console.log(
"admin is instance of models.admin",
adminFound instanceof models.admin
); // true
adminFound.hasoperation_sav(operation_sav);
});
But, hasoperation_sav is still unrecognized as a function.
I have solved it like this:
models.operation_sav.findByPk(4).then(operation_sav => {
models.admin.findByPk(10).then(adminFound => {
console.log(
"admin is instance of models.admin",
adminFound instanceof models.admin
);
// admin is instance of models.admin true
adminFound.hasOperation_sav(operation_sav).then(result => {
console.log("admin has operation sav", result);
//admin has operation sav true
});
});
});
Sorry, this is my first nodeJs app, I'm using SailsJs and this is my code
update: function (req, res) {
Cargo.findOne({id: req.param('id')}).exec(function (err,result) {
result.currency = 2;
if(err) {
console.log(err);
}
result.save(function(err,model){
console.log(err);
console.log(model);
console.log('in');
});
console.log("testing");
})
},
I keep getting "testing" in my console log and not getting any log in save method.
Am I doing it wrong?
Found the issue causing it not going into .save method
My model code are as follow
module.exports = {
tableName: "cargo",
attributes: {
'remark': {
type: 'text'
},
'shipper': {
type: 'integer',
integer: true,
model: 'Company',
columnName:"shipperID",
},
'consignee': {
type: 'integer',
integer: true,
columnName:"consigneeID",
model: 'Company'
},
'packing': {
"type": 'integer',
integer: true,
columnName:"packingID",
equals: function (value) {
return value;
}
},
'commodity': {
'type': "string",
maxLength: 512
},
'status': {
'type': "string",
maxLength: 25
},
'dateIn': {
'type': "datetime"
},
'currency': {
'type': 'integer'
},
'amt': {
'type': 'float'
},
'marking': {
'type': 'string',
maxLength: 25,
required: true
},
'createdAt': {
columnName: 'createdDate'
},
'updatedAt': {
columnName: 'lastModifiedDate'
},
'packages': {
collection: 'CargoPackage',
via: 'cargo'
}
}
};
It's due to "packing" attribute having this "equal" that cause the save method to goes into infinite loop or something. I thought this is a validator for making sure the value is what I want. Well I think its built for other purposes.
I guess for others with similar issues, it will be best to have the model you are working on be as basic as possible to make sure it's not that thing holding up the process.