Getting "model is not associated with other Model" in sequelize when using belongsToMany - postgresql

I am using sequelize with postgreSQL. I have two schemas namely User and Location. A User can have many Locations and a Location can have many Users.
My User Schema is as follows
id: {
type: Sequelize.INTEGER,
autoIncrement: true,
primaryKey: true
},
firstName: {
type: Sequelize.STRING,
require: true
},
middleName: {
type: Sequelize.STRING,
require: false
},
lastName: {
type: Sequelize.STRING,
require: true
},
age: {
type: Sequelize.INTEGER,
require: false
},
email_Id: {
type: Sequelize.STRING,
require: true,
unique: true,
validate: {
isEmail: true
}
}
My Location Schema is as follows:
id: {
type: Sequelize.INTEGER,
autoIncrement: true,
primaryKey: true
},
latitude: {
type: Sequelize.DOUBLE,
require: true
},
longitude: {
type: Sequelize.DOUBLE,
require: true
},
locationAddress: {
type: Sequelize.STRING
},
mailBoxNo: {
type: Sequelize.INTEGER
}
I Am using belongsToMany of sequelize and creating a third table name UserLocation where I have mentioned belongsToMany for both User and Location which is as below:
User.belongsToMany(Location, {
through: 'UserLocation'
});
Location.belongsToMany(User, {
through: 'UserLocation'
});
My requirement is to get all the locations for a given user id. My Code is as follows:
var param = req.body;
var options = {};
if (param.where) {
options.where = param.where;
}
options.include = [{
model: User //User Model
}, {
model: Location //Location Model
}];
//Here userLocation refers to UserLocation Schema
userLocation.findAll(options).then(function (response) {
//Some Logic
}).catch(function (err) {
//Error handling
});
While executing the above code, I getting the following error:
User Model is not associated with UserLocation Model.
I am unable to understand why I am getting the following error. Can somebody help me out with this?

You can use this for getting all the locations of a given user;
User
.findOne({
"where": {
"id": param.where
},
"include": [Location]
})
.then(function(user) {
// should get this user
console.log(user);
// should get all locations of this user
console.log(user.Locations);
})
.catch(function(error) {
// error handling
});

Related

SailsJs/Postgresql - How to create a one way association or one-to-many relation via an unique field

I have two models:
PdfAnnotation.js:
module.exports = {
tableName: "pdf_annotations",
primaryKey: "pk_id",
attributes: {
pk_id: {
type: "number",
autoIncrement: true
},
annotation_id: {
type: "string",
unique: true,
required: true,
},
comments: {
collection: "pdfcomments",
via: "fk_annotation_id"
}
}
};
PdfComments.js:
module.exports = {
tableName: "pdf_comments",
primaryKey: "pk_id",
attributes: {
pk_id: {
type: "number",
autoIncrement: true,
},
fk_annotation_id: {
model: "pdfannotations",
},
comment_content: {
type: "string",
},
}
};
When I run these codes:
PdfAnnotations.create({
annotation_id: "test3",
});
PdfComments.create({
fk_annotation_id: 'test3',
comment_content: 'test',
});
I got this error:
I have followed the documentation: https://sailsjs.com/documentation/concepts/models-and-orm/associations/one-to-many.
The difference between my implementation and the docs is: the constraint I used for PdfComments to PdfAnnotations via an unique field annotation_id(string) not the primary key pk_id(number), so that I got the error.
For some reasons I don't want to use annotation_id as a primary key (such as its type is string)
I'm not familiar with Sails and its ORM, hope to see your help.
Try something like this:
const pdfannotation = await PdfAnnotations.create({
annotation_id: 'test3',
}).fetch();
const pdfcomment = await PdfComments.create({
fk_annotation_id: pdfannotation.id,
comment_content: 'test',
});

MongoDB: Set and get Sub Document Schema

I'm using mongoose and I have users collection shown below, but I now want to allow the user to save a number of articles, an article has a title, subtitle, and body, One user can have many articles.
How can I restructure the users collection to allow the articles to be added
const userSchema: Schema = new Schema(
{
email: { type: String, required: true, unique: true },
fullName: { type: String, required: true },
password: { type: String, required: true },
},
{
timestamps: true,
}
);
I'm using the below to set new data to the user's collection, how do I adapt it to allow me to set and get the new articles detailed above?
const confirmed = await userModel
.findOneAndUpdate(
{ email },
{
$set: { password },
}
)
.exec();
You can set the option strict: false and add(save) new fields to your schema.
const userSchema: Schema = new Schema(
{
email: { type: String, required: true, unique: true },
fullName: { type: String, required: true },
password: { type: String, required: true },
},
{
strict: false,
timestamps: true,
}
);
Here is the docs

ReferenceError: user is not defined in user api

When I open localhost:1337/user I got Internal Server Error
Something isn't right here.
ReferenceError: user is not defined
How can I fix it? My API is not working. I can't insert data in database using html forms in sailsjs.
My user model is:
module.exports = {
attribute: {
firstname: {
type: 'string',
unique: true
},
lastname: {
type: 'string',
unique: true
},
organisationName: {
type: 'string',
unique: true
},
DepatmentName: {
type: 'string',
unique: true
},
DOB: {
type: 'date',
unique: true
},
DOJ: {
type: 'date',
},
DOL: {
type: 'date',
},
Address: {
type: 'string',
},
City: {
type: 'string',
},
State: {
type: 'string',
},
Country: {
type: 'string',
},
email: {
type: 'string',
email: true,
required: true,
unique: true
},
encryptedPassword: {
type: 'string',
},
ContactNumber: {
type: 'integer',
},
//toJSON: function() {
// var obj = this.toObject();
//
// }
}
};
You are calling a variable "user" and it doesn't exist or it's empty. Check youre code for this variable..
In youre usermodel, you only have firstname and lastname. I guess you need one of this. If you want more specific help, then you have to show us some extra coding of the page, not only the model.

Sails js and Sequelize, no associations added to database

This is how my models are structured in sails:
myapp
--api
----controllers
----models
-----User.js
------Role.js
User.js
module.exports = {
attributes:{
id: {
type: Sequelize.INTEGER,
primaryKey: true,
autoIncrement: true
},
username: {
type: Sequelize.STRING,
},
password: {
type: Sequelize.STRING,
}
},
associations: function() {
User.hasOne(Role, {foreignKey: 'id', as: 'role' });
}
};
Role.js
module.exports = {
attributes:{
id: {
type: Sequelize.INTEGER,
primaryKey: true,
autoIncrement: true
},
name: {
type: Sequelize.STRING,
}
}
};
After sails lift, in the postgresql I have users table with id, username, password, createdat and updatedat + roles table with id, name, createdat and updatedat. No foreignKey for Roles in Users table.
How I can fix this?
I'm using sails-hook-sequelize and sails-hook-sequelize-blueprints, can this occur because of them?
Thanks!
Edit:
The correct way was:
module.exports = {
attributes:{
id: {
type: Sequelize.INTEGER,
primaryKey: true,
autoIncrement: true
},
username: {
type: Sequelize.STRING,
},
password: {
type: Sequelize.STRING,
}
},
associations: function() {
User.hasOne(Role, {
as : 'role',
foreignKey: {
name: 'roleId',
allowNull: false
}
});
}
};
The createdAt and updatedAt columns are added by default unless you set the timestamps option to false. See the docs.
To add foreign key constraints, you need to define associations for the Roles model.

Eager Loading : How to disable specific fields of included table

I am trying to do Eager Loading in Sequelize with PostgreSQL where I need to find the Users which have a given specific Mail id or basically, i am performing find operation on Mail model while using include to include User model
UserModel :
module.exports = function (sequelize, Sequelize) {
var User = sequelize.define('User', {
userId: {
type: Sequelize.INTEGER,
primaryKey: true,
autoIncrement: true
},
firstname: {
type: Sequelize.STRING,
require: true
},
lastname: {
type: Sequelize.STRING,
require: true
},
age: {
type: Sequelize.INTEGER,
require: true
},
phone: {
type: Sequelize.STRING,
require: true
},
location: {
type: Sequelize.STRING,
require: true
},
createdAt: {
type: Sequelize.DATE,
defaultValue: Sequelize.NOW
},
updatedAt: {
type: Sequelize.DATE,
defaultValue: Sequelize.NOW
}
});
return User;
};
MailModel :
module.exports = function (sequelize, Sequelize) {
var User = require('./User.js')(sequelize, Sequelize)
var Mail = sequelize.define('Mail', {
name: {
type: Sequelize.STRING,
require: true
}
});
Mail.belongsTo(User);
return Mail;
};
MailController :
var db = require('../services/db.js');
module.exports = {
create: function (req, res, next) {
var Mailm = db.MailModel;
var name = req.body;
try {
db.sequelize.sync().then(function () {
Mailm.create(name).then(function (found) {
return res.json({
success: true,
message: found.get({
plain: true
})
});
})
});
} catch (ex) {
res.json({
success: false,
exception: ex
});
return;
}
},
query: function (req, res, next) {
var Mailm = db.MailModel;
var Userm = db.UserModel;
var name = req.body;
var option = {};
option.where = name;
option.include = [{
model: Userm
}];
try {
Mailm.findAll(option).then(function (found) {
console.log(found);
return res.json({
success: true,
message: found
});
});
} catch (ex) {
res.json({
success: false,
exception: ex
});
return;
}
}
};
It is returning me the records of both User and Mail table in exactly the right way .
Output :
{
"success": true,
"message":[
{
"id": 2,
"name": "Mailb2",
"createdAt": "2015-07-30T07:32:51.807Z",
"updatedAt": "2015-07-30T07:32:51.807Z",
"UserUserId": 2,
"User":{
"userId": 2,
"firstname": "Prerna",
"lastname": "Jain",
"age": 20,
"phone": "9812123456",
"location": "Sirsa",
"createdAt": "2015-07-30T07:30:48.000Z",
"updatedAt": "2015-07-30T07:30:48.000Z"
}
}
]
}
But I want to disable createdAt and updatedAt fields of User table so that it does not give me these two fields in the output for User.
I have tried a lot as of how to do this but still in vain.Can anyone please help me out.
I bet this is coming late, add attribute/properties to your models called timestamps, it accepts a boolean as a value. For example:
module.exports = function (sequelize, Sequelize) {
var User = require('./User.js')(sequelize, Sequelize)
var Mail = sequelize.define('Mail', {
name: {
type: Sequelize.STRING,
require: true
}
},
{
// This does the magic
timestamps: false,
});
Mail.belongsTo(User);
return Mail;
};
Also, add it to the User model:
var User = sequelize.define('User', {
userId: {
type: Sequelize.INTEGER,
primaryKey: true,
autoIncrement: true
},
firstname: {
type: Sequelize.STRING,
require: true
},
lastname: {
type: Sequelize.STRING,
require: true
},
age: {
type: Sequelize.INTEGER,
require: true
},
phone: {
type: Sequelize.STRING,
require: true
},
location: {
type: Sequelize.STRING,
require: true
},
createdAt: {
type: Sequelize.DATE,
defaultValue: Sequelize.NOW
},
updatedAt: {
type: Sequelize.DATE,
defaultValue: Sequelize.NOW
}
},
{
timestamps: false
});
return User;
};
You can use
Model.findAll({
attributes: { exclude: ['baz'] }
});
more examples with attributes - http://docs.sequelizejs.com/en/latest/docs/querying/#attributes