Bookshelf get related data attributes is empty - node.js

I seem to have an issue with retrieving attributes from a related model.
Models:
// DB = export of Bookshelf
// Signup model
var DB = require('../db').DB;
var UserMeta = require('./usersmeta');
var Signup = DB.Model.extend({
tableName: 'tblSignups',
idAttribute: 'id',
hasTimestamps: true,
usermeta: function() {
return this.belongsTo(UserMeta);
}
});
module.exports = Signup;
// Usermeta model
var DB = require('../db').DB;
var User = require('./users');
var UserMeta = DB.Model.extend({
tableName: 'tblUsersMeta',
idAttribute: 'id',
hasTimestamps: true,
user: function() {
return this.belongsTo(User);
}
});
module.exports = UserMeta;
Admin Signup route:
router.get('/signups', function(req, res, next) {
model.SignUp.fetchAll({withRelated: ['usermeta']}).then(function(collection) {
for(var i = 0; i < collection.toArray().length; i++){
console.log('Signup ' + i + '\n--------------------------');
console.log(collection.toArray()[i]);
console.log('Related usermeta\n--------------------------');
console.log(collection.toArray()[i].related('usermeta'));
}
res.render('admin/pages/signups', {title: 'signups', error: false, signups: collection.toArray()});
}).catch(function(err) {
res.status(500).json({error: true, data: {message: err.message}});
});
});
This is what the console log shows me:
Signup 0
--------------------------
ModelBase {
attributes:
{ id: 2,
usermeta_id: 5,
state: 'pending',
created_at: Thu May 05 2016 17:21:13 GMT+0200 (Romance Daylight Time),
updated_at: Thu May 05 2016 17:21:13 GMT+0200 (Romance Daylight Time) },
_previousAttributes:
{ id: 2,
usermeta_id: 5,
state: 'pending',
created_at: Thu May 05 2016 17:21:13 GMT+0200 (Romance Daylight Time),
updated_at: Thu May 05 2016 17:21:13 GMT+0200 (Romance Daylight Time) },
changed: {},
relations:
{ usermeta:
ModelBase {
attributes: {},
_previousAttributes: {},
changed: {},
relations: {},
cid: 'c38',
relatedData: [Object] } },
cid: 'c35',
id: 2 }
Related usermeta
--------------------------
ModelBase {
attributes: {},
_previousAttributes: {},
changed: {},
relations: {},
cid: 'c38',
relatedData:
RelationBase {
targetTableName: 'tblUsersMeta',
targetIdAttribute: 'id',
type: 'belongsTo',
target:
{ [Function]
NotFoundError: [Function: ErrorCtor],
NoRowsUpdatedError: [Function: ErrorCtor],
NoRowsDeletedError: [Function: ErrorCtor] },
foreignKey: 'tblUsersMetum_id',
parentId: undefined,
parentTableName: 'tblSignups',
parentIdAttribute: 'id',
parentFk: undefined } }
So as you can see the related model attributes is empty. I saved my usermeta as follows:
userMeta.save().then(function(usermeta) {
var signup = new model.SignUp({
usermeta_id: usermeta.attributes.id
});
signup.save().then(function() {
req.flash('success', 'Success!');
res.redirect('/signup');
}).catch(function(err) {
res.status(500).json({error: true, data: {message: err.message}});
});
}).catch(function (err) {
res.status(500).json({error: true, data: {message: err.message}});
});
Within the database the usermeta's id (in the signup table) is set correctly. What am I doing wrong here?

It appears that something is wrong with your models. When you're setting up the relation between the models you use belongsTo in both examples - that can't be right. I don't know what is the relation between them (many-to-many? one-to-many?). If it's many-to-many you need to use belongsToMany and if it's one-to-many you need to set hasMany on the model that does not hold the foreign key in the database and belongsTo to the model that has the foreign key in the database.
See this http://bookshelfjs.org/#one-to-many and this http://bookshelfjs.org/#many-to-many
Hope this helps!

Related

How to join two tables? - Cannot read property 'getTableName' of undefined

Users Model File
'use strict';
module.exports = (sequelize, DataTypes) => {
const user = sequelize.define('user', {
"access_role_id":DataTypes.INTEGER,
"user_type":{
type: DataTypes.ENUM,
values: ['A', 'V', 'U']
},
"login_access":{
type: DataTypes.ENUM,
values: ['APP', 'WEB', 'BOTH']
},
"username": DataTypes.STRING,
"email": DataTypes.STRING,
"updated_at":DataTypes.DATE,
"created_at":DataTypes.DATE,
}, {
"timestamps": false,
"createdAt": false,
'updatedAt': false,
"underscored": true,
"freezeTableName": false,
});
user.associate = function(models) {
// associations can be defined here
models.user.belongsTo(models.product, {targetKey: 'id',foreignKey: 'created_by'});
};
return user;
};
User Controller File
const dbConfig = require( '../../../db/models/index');
let users =require('../../../db/models/user')(dbConfig.sequelizeDB,dbConfig.Sequelize);
module.exports = {
// GET /customer/:id
getCustomer: function(req, res, next) {
users.findAll({
include: [{
model: users.product,
}]
}).then(function (stores) {
if (stores.length === 0) {
res.json('There are no stores in the database');
}
res.json(stores);
});
},
};
I am unable to get the product table data. It always shows an error:
Unhandled rejection TypeError: Cannot read property 'getTableName' of undefined.
Why the product table is not fetched in users model? How can I access this product table data by the users model?
Update your User Controller File as
const dbConfig = require( '../../../db/models/index');
let users =require('../../../db/models/user')(dbConfig.sequelizeDB,dbConfig.Sequelize);
let product=require('../../../db/models/product')(dbConfig.sequelizeDB,dbConfig.Sequelize);
module.exports = {
// GET /customer/:id
getCustomer: function(req, res, next) {
users.findAll({
include: [{
model: product,
}]
}).then(function (stores) {
if (stores.length === 0) {
res.json('There are no stores in the database');
}
res.json(stores);
});
},
};

How to get data in sequelize using Noje js

This is code i have used, fetched the all data in database, but i have not getting in value. I'm new for sequelize.
Project.findAll({ raw: true}).then(function (users) {
console.log(users);
console.log(users.dataValues);
}).catch(function (err) {
console.log('Oops! something went wrong, : ', err);
});
This is Output:
This is console.log(users);
[ DAO {
dataValues:
{ idProject: 1,
projectName: 'Symfony',
isActive: '1',
createdAt: 2018-10-23T06:32:43.000Z,
modifiedAt: 2018-10-23T06:32:43.000Z },
_previousDataValues:
{ idProject: 1,
projectName: 'Symfony',
isActive: '1',
createdAt: 2018-10-23T06:32:43.000Z,
modifiedAt: 2018-10-23T06:32:43.000Z },
options: { isNewRecord: false, isDirty: false, raw: true },
hasPrimaryKeys: true,
selectedValues:
RowDataPacket {
idProject: 1,
projectName: 'Symfony',
isActive: '1',
createdAt: 2018-10-23T06:32:43.000Z,
modifiedAt: 2018-10-23T06:32:43.000Z },
__eagerlyLoadedAssociations: [],
isNewRecord: false }.....
This is console.log(users.dataValues);
undefined
How is it possible?
When you use findAll, it returns an array, as you can see here in the documentation:
http://docs.sequelizejs.com/class/lib/model.js~Model.html#static-method-findAll
so you should iterate over this array, like so:
Project.findAll({ raw: true})
.then(projects => {
projects.forEach(project => {
console.log(project);
console.log('project name', project.projectName);
})
}).catch(function (err) {
console.log('Oops! something went wrong: ', err);
});
Optionally you could use Async/Await for a cleaner code:
try {
const projects = await Project.findAll({ raw: true});
projects.forEach(project => {
console.log('project name ', project.projectName);
})
} catch(err) {
console.log('Oops! something went wrong: ', err);
}

Sequelize include return data

I am using Sequelize express with Node.js as the backend. I have models Event and models buyer with relation many to many
Model Event:
module.exports = function (sequelize, DataTypes) {
var Event = sequelize.define("Event", { //...},
{
tableName: 'event',
timestamps: false,
freezeTableName: true,
classMethods: {
associate: function (models) {
Event.hasMany(models.Meetings, {foreignKey: 'event_id'});
Event.belongsToMany(models.Buyer, {
through: 'BuyerPresent'});
Event.belongsToMany(models.Seller, {
through: 'SellerPresent'});
}
}
});
return Event;
};
Model Seller:
module.exports = function (sequelize, DataTypes) {
var Seller = sequelize.define("Seller", { //...
}, {
tableName: 'seller',
timestamps: false,
freezeTableName: true,
classMethods: {
associate: function (models) {
Seller.hasMany(models.Meetings, {foreignKey: 'seller_id'});
Seller.belongsToMany(models.Event, {
through: 'SellerPresent'});
}
}
});
return Seller;
};
I run the query and send the data with
res.render('path', {'results':seller})
:
function findIdSeller(selectEvent) {
var match = {
where: {
event: selectEvent
},
// include: {
// model: Seller
// },
include: [{
model: Seller,
nested: false
}],
// plain:true
raw: true
};
return models.Event.findAll(match)
}
exports.findDataSellerPromise = function (selectEvent) {
return findIdSeller(selectEvent).then(function (result) {
return result.map(function(seller) {
console.log('SELLINFO: ', seller);
return seller;
});
});
};
In the terminal i received:
{
id: 4,
incoming: 2,
event: 4,
'Sellers.id': 1,
'Sellers.name_firm': 'kdm srl',
'Sellers.site': 'www.terrebasse.com'
}
How can I return an item as:
{
id: 4,
incoming: 2,
event: 4,
Sellers: {
id': 1,
name_firm: 'kdm srl',
site: 'www.terrebasse.com'
}
}
Remove the raw: true from the query
That would give sellers as instance on each event
Something like
{
//Event1 properties
Sellers: {
// Associated sellers properties
}
}
Guess I am too late to the party..
But for anyone else facing similar issue

How to insert initial data using sequelize migrations/seeds?

I'm trying to create my initial migration to populate the test database but I can't get it working. This is what I have in my migration:
'use strict';
module.exports = {
up: function (queryInterface, Sequelize) {
return [
queryInterface.bulkInsert('Users', [
{ username: "user1" },
{ username: "user2" }
])];
},
down: function (queryInterface, Sequelize) {
return queryInterface.dropTable('Users');
}
};
And I get this error:
== 20151024144833-create-conjugation: migrating =======
{ [SequelizeUniqueConstraintError: Validation error]
name: 'SequelizeUniqueConstraintError',
message: 'Validation error',
errors: [],
fields: [] }
There must be an easier way to do this. I've checked other SO questions, but the syntax has changed in the current version of sequelize.
UPDATE
Ok, I realized my mistake: I was assuming that sequelize would take care of the timestamps. This fixes the problem:
up: function (queryInterface, Sequelize) {
console.log(User);
return [
queryInterface.bulkInsert('Users', [
{ username: "user1", createdAt: Date.now(), updatedAt: Date.now() },
{ username: "user2", createdAt: Date.now(), updatedAt: Date.now() }
])
];
}
But I'm still wondering if this is the right way to seed my database. Is there a way to do it using User.create({})?
new Date()
also required for mysql, i.e.
return queryInterface.bulkInsert('users', [
{
"Forename":"A",
"Surname": "User",
"UserType":"1",
"Email":"auser#gmail.com",
"Password":"password",
"LastLogin":0,
"Tokens": JSON.stringify({"tokens":[]}),
"CreatedBy": 999,
"CreatedAt": new Date(),
"UpdatedAt": new Date()
}]);
You can use next:
const City = sequelize.define('city', {
name: { type: Sequelize.STRING },
order_: { type: Sequelize.INTEGER }
});
City.sync().then(() => {
City.create({
name: 'Neuquen',
order_: 0
});
City.create({
name: 'General Roca',
order_: 1
});
});
Or read about "migrations" at http://docs.sequelizejs.com/en/latest/docs/migrations/
An alternative could be use : sequelize fixtures , you could init your tables with default data declared as a json file or other format.
For a quick and easy way (without seeds or migrations) on sequelize v6:
I modified my sequelize.sync() call:
import { Sequelize } from 'sequelize';
// This will create an in-memory sqlite db
const sequelize = new Sequelize('sqlite::memory:', {
logging: sequelizeLogger
});
await sequelize
.sync({ force: true })
.then(() => {
// seed db
Users.create({ username: 'user1' })
});

Retrieving model using mongoose

I want to retrieve the whole model from my database searching by an "id".
Which query is best to use in this case?
This is how my schema looks:
{ _id: 54b5ed4b967a4e3b96fe8a39,
email: 'blabla#yahoo.com',
__v: 0,
deleted: false,
createdAt: Tue Jan 13 2015 23:15:07 GMT-0500 (EST),
shipping: {},
profile: { picture: '', location: 'Romania', name: 'bla' },
tokens: [],
role: 'shopper'}
and what I have is: 54b5ed4b967a4e3b96fe8a39
If you know the type of Model that you are looking for, i.e. Person. Just do:
var id = "54b5ed4b967a4e3b96fe8a39";
Person.findById(id, function(err, person) {
if (err) {
return console.log('oh no! error', err);
}
console.log('found person', person);
});
Documentation here

Resources