How to stop the autoincrement for id in sails.js - node.js

//Controller
afterCreate: function(datas, cb) {
console.log("Data Id : ",datas.id);//Id:90150
var menudetails = { id : datas.id };//Id:90150
MenuDetail.create(menudetails).exec(function createMD(err, created){
console.log("MenuDetail",created);
console.log("MenuDetail Id : ",created.id);//Id:90103
if(err) return cb(err);
});
cb();
}
Here I'm trying to create the new record in MenuDetail with specific id, but it don't create the record for that specified id, it will generate the id which is autoincremented by previous id.
I need the record with specified id which is given as paramater.

An easy way to do this is to overwrite the id attribute on your model like so:
module.exports = {
attributes: {
id: {
type: 'integer',
autoIncrement: false,
unique: true,
primaryKey: true
}
}
}
Doing so will require you to set the id on each record you create.

Related

Sequelize "SELECT * from tablename" query

Why the query below executes SELECT id, email, name FROM users AS users WHERE users.email = 'admin#admin.com'; rather than SELECT * from users WHERE email = admin#admin.com ?
http://docs.sequelizejs.com/en/latest/docs/querying/#where
Documentation states that it'll run a SELECT * query when I do findAll(), but it does something different in my example. What's missing here?
Here's my users model.
var user = sequelize.define('users', {
id : {
type : Sequelize.INTEGER,
primaryKey : true,
autoIncrement : true
},
email : {
type : Sequelize.STRING
},
name : {
type : Sequelize.STRING
}
},
{
tableName: 'users',
freezeTableName: true
});
And this is my query. It seems that it only selects defined columns, but I don't want this.
var email = "admin#admin.com";
user.findAll({where: {email: email}}).then(function (user) {
res.send(user);
}).error(function (err) {
console.log("Error:" + err);
});
This is expected behavior of sequelize selecting only the columns which you have defined. If you want to select all of the columns using sequelize you must define them in your model.

Soft delete in Sails/Waterline

Trying to delete a user model using:
//Hard Delete
User.destroy({id:userId}, function(err, res){
//Hard Delete
})
I need to do a soft delete on User model and currently setting a flag isDeleted to true on delete and updating document:
updateUser.isDeleted = true;
User.update({id:userId}, updateUser, function(err, res){
Update project
})
and while fetching documents I am doing a check If isDeleted - true or not.
Is there any In-built feature provided by Sails or Waterline which I can configure to perform a soft delete and avoid updating and then fetching based on isDeleted flag?
you can use beforeFind() life cycle function for filter of soft deleted records
model: parrot,js
module.exports = {
attributes: {
// e.g., "Polly"
name: {
type: 'string'
},
// e.g., 3.26
wingspan: {
type: 'float',
required: true
},
// e.g., "cm"
wingspanUnits: {
type: 'string',
enum: ['cm', 'in', 'm', 'mm'],
defaultsTo: 'cm'
},
// e.g., [{...}, {...}, ...]
knownDialects: {
collection: 'Dialect'
},
isDeleted:{
type:'boolean'
}
},
beforeFind: function(values, cb) {
values.isDeleted = false;
cb();
}
}
ParrotController.js
module.exports = {
// getting default parrots isDeleted = true
list: function (req, res) {
Parrot
.find()
.exec(function(err, parrots) {
if(err) return res.send({ flag:false, data:[], message:"Error." });
if(parrots && parrots.length){
return res.send({ flag:true, data:parrots, message:"Success." });
}
else{
return res.send({ flag:false, data:[], message:"Parrot list is empty." });
}
});
}
};
There is no soft-delete feature built into sails, and I doubt there will be.
Here's a challenge: why not write your own? Waterline supports class methods! Of course you would have to do it for each model or create a service... which might be even more effective.

Get last inserted id Sequelize

I'm using Sequelize and I'm trying to get the last inserted ID in raw query.
My query is
.query(Sequelize.Utils.format(["insert into MyTable (field1, field2) values (?,?)", val1, val2])
The query is done perfectly, but the result on success event is null.
Can someone help?
Thanks.
After some researches and zillions attempts, I understood how callee object work in sequelizeJs.
please, correct me if my answer is wrong.
the callee object needs this structure
{__factory:{autoIncrementField: 'parameterName'}, parameterName: '' }
in this case "parameterName" is the field that will store the new ID, sequelize looks for __factory.autoIncrementField to set value of last inserted id into property with its value (value of __factory.autoIncrementField).
so, my call to querys method would be
.query(sequelize.Utils.format(tempInsert), {__factory:{autoIncrementField: 'parameterName'}, parameterName: '' }, {raw: true})
this will result in object like that
{ __factory: { autoIncrementField: 'parameterName' }, parameterName: newInserted_ID }
thanks for all, and I hope this can help someone.
You have to add autoIncrement property in model definition.
const Article = sequelize.define('articles', {
id: {
type: Sequelize.INTEGER,
primaryKey: true,
autoIncrement: true
}, {},
{
createdAt: false,
updatedAt: false
});
Then, you can access last inserted id with property in model definition.
Article.create(article)
.then(result => console.log(result.id));
Yes your answer is working. Another way would be
var Sequelize = require("sequelize")
var sequelize = new Sequelize('test', 'root', 'root', {dialect: 'mysql'})
var Page = sequelize.define( 'page', {
type : {type: Sequelize.STRING(20)},
order : {type: Sequelize.INTEGER, defaultValue: 1}
},{
timestamps: false,
underscored: true
})
Page.__factory = {autoIncrementField: 'id'}
Page.id = ''
sequelize.query('INSERT INTO pages SET `type` = ?, `order` = ?, `topic_version_id` = ?', Page, {raw: false}, ['TEXT', 1, 1] ).success(function(page) {
console.log(page)
Page.find(page.id)
.success(function(result){
console.log(result)
})
})
const addAuthUser = await authModel.create(
{
username: username,
password: hashedPassword
});
if (!addAuthUser) {
return next(new HttpError('SignUp Failed!', 401));
}
// this last inser id
console.log(addAuthUser.id)

Can a Schema use it's own model to validate?

For example, say I have a user schema, and I want to validate that the username is unique before even attempting to save the user to the database.
...
UserSchema.path('username')
.validate(function (value, respond) {
User.findOne({ username: this.username }) // This isn't valid.
.lean()
.select('_id')
.exec(function (err, user) {
if (err) {
winston.warn('User_username: Error looking for duplicate users');
respond(false);
}
// If a user was returned, then the user is non-unique!
if (user) {
respond(false);
}
respond(true);
});
});
...
var User = mongoose.model('User', UserSchema);
I know I could use mongoose.model('User').findOne(...) but that just seems a bit silly, is there no better way to do it?
You can create an unique index in your schema by setting unique: true. This will make use of the unique index option that is available in mongodb. Here is an example snippet from one of my models using this option:
// The (generated) uniform resource locator
url: {
// ... which is required ...
required: true,
// ... which is an unique index ...
unique: true,
// ... and is a string.
type: String
}
Compound key from comments:
Schema.index({ username: 1, accountCode: 1 }, { unique: true })

MeanJS MongoDb insert issue

I'm creating an application using MEANJS. I've a mongoose schema defined like this:
var UserdetailSchema = new Schema({
fullName: {
type: String,
trim: true
},
userName: {
type: String,
trim: true
},
mobile: {
type: String,
default: '',
trim: true
},
address: {
type: String,
trim: true
},
suburb: {
type: String
},
user: {
type: Schema.ObjectId,
ref: 'User'
}
});
mongoose.model('Userdetail', UserdetailSchema);
What I'm trying to achieve is after login user is redirected to edit view to update rest of the info like "mobile, suburb, address" etc which is in userdetails schema.
This is my controller. I've changed default create() method to the following: I'm redirecting to the edit it as soon as the first step of inserting is complete.
// Create new Userdetail for current user
function create(FullName,UserName) {
// Create new Userdetail object
var userdetail = new Userdetails ({
fullName: FullName,
userName: UserName
});
// Redirect after save
userdetail.$save(function(response) {
$location.path('userdetails/' + response._id+'/edit');
console.log(response._id);
// Clear form fields
//$scope.name = '';
}, function(errorResponse) {
console.log(errorResponse.data.message);
$scope.error = errorResponse.data.message;
});
};
To create a user details I'm only inserting fullName, and userName as a first step and updating it later.
issue is, it is only allowing me 1 userdetails to insert and if I try to insert another userdetails of another user. it gives an error "Name already exists", though there is no name in the schema.
Server side code to create userdetails
/**
* Create a Userdetail
*/
exports.create = function(req, res) {
var userdetail = new Userdetail(req.body);
userdetail.user = req.user;
userdetail.save(function(err) {
if (err) {
return res.status(400).send({
message: errorHandler.getErrorMessage(err)
});
} else {
res.jsonp(userdetail);
}
});
};
I got it working after droping my collection "userdetails" from shell and trying inserting again. I followed this link Mongodb- Add unique index on an existing collection . It was more of MongoDB issue.

Resources