Sequelize Can't Add Value into Associated Object - express

I am trying to to create an object with a child (association) that has the Id of the created object passed as a value to its property. I have tried to follow the documentation, but there is no value being passed with the SQL command.
Here is the SQL query:
INSERT INTO `organization` (`organization_id`,`organization_name`,`admin`,`updatedAt`,`createdAt`) VALUES (DEFAULT,'dfsadfadsfa','ter#test.cm','2016-01-08 02:23:04','2016-01-08 02:23:04');
No reference to user
Here is the route inserting into organization:
var express = require('express');
var appRoutes = express.Router();
var passport = require('passport');
var localStrategy = require('passport-local').Strategy;
var models = require('../models/db-index');
appRoutes.route('/sign-up/organization')
.get(function(req, res){
models.User.find({
where: {
user_id: req.user.email
}, attributes: [ 'user_id', 'email'
]
}).then(function(user){
res.render('pages/sign-up-organization.hbs',{
user: req.user
});
})
})
.post(function(req, res, user){
models.Organization.create({
organizationName: req.body.organizationName,
admin: req.body.admin,
User: [{
organizationId: req.body.organizationId
}]
}, { include: [models.User] }).then(function(){
console.log(user.user_id);
res.redirect('/app');
}).catch(function(error){
res.send(error);
console.log('Error at Post');
})
});
Here is the form submission:
<div class="container">
<div class="col-md-6 col-md-offset-3">
<form action="/app/sign-up/organization" method="post">
<p>{{user.email}}</p>
<input type="hidden" name="admin" value="{{user.email}}">
<input type="hidden" name="organizationId">
<label for="sign-up-organization">Company/Organization Name</label>
<input type="text" class="form-control" id="sign-up-organization" name="organizationName" value="" placeholder="Company/Organization">
<br />
<button type="submit">Submit</button>
</form>
user.js model:
var bcrypt = require('bcrypt-nodejs');
module.exports = function(sequelize, DataTypes) {
var User = sequelize.define('user', {
user_id: {
type: DataTypes.INTEGER,
autoIncrement: true,
primaryKey: true
},
firstName: {
type: DataTypes.STRING,
field: 'first_name'
},
lastName: {
type: DataTypes.STRING,
field: 'last_name'
},
email: {
type: DataTypes.STRING,
isEmail: true,
unique: true
},
password: DataTypes.STRING,
organizationId: {
type: DataTypes.INTEGER,
field: 'organization_id',
allowNull: true
}
}, {
freezeTableName: true,
classMethods: {
generateHash: function(password) {
return bcrypt.hashSync(password, bcrypt.genSaltSync(8), null);
},
},
instanceMethods: {
validPassword: function(password) {
return bcrypt.compareSync(password, this.password);
},
},
});
return User;
}
organization.js model:
module.exports = function(sequelize, DataTypes) {
var Organization = sequelize.define('organization', {
organizationId: {
type: DataTypes.INTEGER,
field: 'organization_id',
autoIncrement: true,
primaryKey: true
},
organizationName: {
type: DataTypes.STRING,
field: 'organization_name'
},
admin: DataTypes.STRING,
members: DataTypes.STRING
},{
freezeTableName: true,
classMethods: {
associate: function(db) {
Organization.hasMany(db.User, {foreignKey: 'user_id'});
},
},
});
return Organization;
}
db-index.js: where the two are associated:
var Sequelize = require('sequelize');
var path = require('path');
var config = require(path.resolve(__dirname, '..', '..','./config/config.js'));
var sequelize = new Sequelize(config.database, config.username, config.password, {
host:'localhost',
port:'3306',
dialect: 'mysql'
});
sequelize.authenticate().then(function(err) {
if (!!err) {
console.log('Unable to connect to the database:', err)
} else {
console.log('Connection has been established successfully.')
}
});
var db = {}
db.Organization = sequelize.import(__dirname + "/organization");
db.User = sequelize.import(__dirname + "/user");
db.Annotation = sequelize.import(__dirname + "/annotation");
db.Organization.associate(db);
db.Annotation.associate(db);
db.sequelize = sequelize;
db.Sequelize = Sequelize;
sequelize.sync();
module.exports = db;

When I use Sequelize, I usually create a function that creates an instance of the sequelize model using the build method and I use the instance to save that instance to the database. With the returned instance you can do whatever you need.
var instance = models.Organization.build(data);
instance.save().then(function(savedOrgInstance){
savedOrgInstance.createUser(userData).then(function(responseData){
//do whatever you want with the callback })
})
I can't say I've seen a create statement as you've written it. What is the extra include statement for?
That should give that newly created user the association you're looking for.
You should checkout the setAssociaton, getAssociation, createAssociation methods in the docs. http://docs.sequelizejs.com/en/latest/docs/associations/

Related

Password to be hashed during PATCH request

During patch request, along with other changes (e.g. "name" and "email" if required) password changed and then to be hashed.
I have the following code so far patch route:
router.patch("/edit/:_id", (req, res, next) => {
User.findOneAndUpdate({_id : req.params._id},
{$set:
{
email: req.body.email,
name: req.body.name,
password: req.body.password
},
},
{
new : true,
upsert: true,
omitUndefined: true
}
)
.then(user => res.json(user))
.catch(err => console.log(err));
});
Model/Schema
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
var ObjectId = mongoose.Schema.Types.ObjectId;
// Create Schema
const UserSchema = new Schema({
name: {
type: String,
required: true
},
email: {
type: String,
required: true,
unique: true
},
password: {
type: String,
required: true
},
date: {
type: Date,
default: Date.now
}
});
module.exports = User = mongoose.model("users", UserSchema);
I want to use "bcryptjs" to hash user's password. Please en-light me. Thanks in advance.
All I did in order to solve, add findOneandUpdate pre hooks on schema.
Here is code:
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
var ObjectId = mongoose.Schema.Types.ObjectId;
const bcrypt = require("bcryptjs");
// Create Schema
const UserSchema = new Schema({
name: {
type: String,
required: true
},
email: {
type: String,
required: true,
unique: true
},
password: {
type: String,
required: true
},
date: {
type: Date,
default: Date.now
}
});
UserSchema.pre('findOneAndUpdate', async function (next) {
await this.updateOne({},{ $set: { password: bcrypt.hashSync(this.getUpdate().$set.password, 10) }})
});
module.exports = User = mongoose.model("users", UserSchema);

Transpiled GraphQL with Babel is throwing error "Cannot call class as function"

I am trying to get running GraphQL server. I have simple schema in GraphQL
import {
GraphQLObjectType,
GraphQLInt,
GraphQLString,
GraphQLList,
GraphQLSchema
} from 'graphql'
import db from './models'
const user = new GraphQLObjectType({
name: "user",
description: 'This represents a user',
fields: () => {
return {
id: {
type: GraphQLInt,
resolve(user) {
return user.id
}
},
firstName: {
type: GraphQLString,
resole(user) {
return user.firstName
}
},
lastName: {
type: GraphQLString,
resole(user) {
return user.lastName
}
},
email: {
type: GraphQLString,
resole(user) {
return user.email
}
},
createdAt: {
type: GraphQLString,
resole(user) {
return user.createdAt
}
},
updatedAt: {
type: GraphQLString,
resole(user) => {
return user.updatedAt
}
}
}
}
})
const Query = new GraphQLObjectType({
name: 'Query',
description: 'This is root Query',
fields: () => {
return {
users: {
type: GraphQLList(user),
args: {
id: {
type: GraphQLInt
},
email: {
type: GraphQLString
}
},
resolve(root, args) {
return db.user.findAll({where: args})
}
}
}
}
})
const Schema = new GraphQLSchema({
query: Query
})
export default Schema
I am transpile it with babel into ES5, but every time when I try run it with express
import GraphHTTP from 'express-graphql'
import Schema from './schema'
app.use('/grapql', GraphHTTP({
schema: Schema,
pretty: true,
graphiql: true
}))
I am getting this error
\node_modules\graphql\type\definition.js:41
function _classCallCheck(instance, Constructor) { if (!instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }                                                             
TypeError: Cannot call a class as a function
I check it again and again if i have some typing error but i didnt find enything.
instead of type: GraphQLList(user) use type: new GraphQLList(user)
GraphQLList is a class and you have to create it's instance and use, but you have called it as a function.
const Query = new GraphQLObjectType({
name: 'Query',
description: 'This is root Query',
fields: () => {
return {
users: {
type: new GraphQLList(user),
args: {
id: {
type: GraphQLInt
},
email: {
type: GraphQLString
}
},
resolve(root, args) {
return db.user.findAll({where: args})
}
}
}
}
})

Sequelize Append Value on Update

I am trying to append a value to one of my objects fields with an .update method, but my current code replaces the value in the field (organization.members) with the new value captured by the field during the post method. I was looking in the documentation for a way to append the value (comma-separated, but I didn't see anything related to appending a value to my object property.
Here is my route:
var express = require('express');
var appRoutes = express.Router();
var passport = require('passport');
var localStrategy = require('passport-local').Strategy;
var models = require('../models/db-index');
appRoutes.route('/settings')
.get(function(req, res){
models.Organization.find({
where: {
organizationId: req.user.organizationId
}, attributes: ['organizationName','admin','members']
}).then(function(organization){
res.render('pages/app/settings.hbs',{
user: req.user,
organization: organization
});
})
})
.post(function(req, res, user){
models.Organization.update({
members: req.body.addMember
},{ where: {
organizationId: req.user.organizationId
}}).then(function(){
console.log("User added to Organization");
res.redirect('/app/settings');
});
});
Here is the organization model:
module.exports = function(sequelize, DataTypes) {
var Organization = sequelize.define('organization', {
organizationId: {
type: DataTypes.INTEGER,
field: 'organization_id',
autoIncrement: true,
primaryKey: true
},
organizationName: {
type: DataTypes.STRING,
field: 'organization_name'
},
admin: DataTypes.STRING,
members: DataTypes.STRING
},{
freezeTableName: true,
classMethods: {
associate: function(db) {
Organization.hasMany(db.User, {foreignKey: 'user_id'});
},
},
});
return Organization;
}
Here is the form:
<div class="row">
<div class="col-md-8 col-md-offset-2">
<div class="annotation-form">
<h2>Add User</h2>
<form action="/app/settings" method="post">
<input name="addMember" type="text" value="">
<button type="submit">Add User</button>
</form>
<h2><u>Additional Users</u></h2>
{{#each organization}}
<li>{{this.members}}</li>
{{else}}
<p>No additional users</p>
{{/each}}
</div>
</div>
</div>
db-index.js:
var Sequelize = require('sequelize');
var path = require('path');
var config = require(path.resolve(__dirname, '..', '..','./config/config.js'));
var sequelize = new Sequelize(config.database, config.username, config.password, {
host:'localhost',
port:'3306',
dialect: 'mysql'
});
sequelize.authenticate().then(function(err) {
if (!!err) {
console.log('Unable to connect to the database:', err)
} else {
console.log('Connection has been established successfully.')
}
});
var db = {}
db.Organization = sequelize.import(__dirname + "/organization");
db.User = sequelize.import(__dirname + "/user");
db.Organization.associate(db);
db.sequelize = sequelize;
db.Sequelize = Sequelize;
sequelize.sync();
module.exports = db;
I had a similar issue, in my case I was using mySQL and using the underlying CONCAT function.
The reason I am not using + to concatenate string is because you might get an SQL syntax error if your string contains a new line
models.Organization.update({
members: Sequelize.fn('CONCAT', Sequelize.col("members"),req.body.addMember)
},{ where: {
organizationId: req.user.organizationId
}}).then(function(){
console.log("User added to Organization");
res.redirect('/app/settings');
});

Sequelize Association Error Not Associated

I am trying to associate my User model with my Organization model, but I'm running into an error that says, Error: user is not associated to organization! despite the fact that I am following the process to associate the User to my Organization. Is it possible that the type of association method that I am using is causing the problem?
User Model (user.js):
var bcrypt = require('bcrypt-nodejs');
module.exports = function(sequelize, DataTypes) {
var User = sequelize.define('user', {
user_id: {
type: DataTypes.INTEGER,
autoIncrement: true,
primaryKey: true
},
firstName: {
type: DataTypes.STRING,
field: 'first_name'
},
lastName: {
type: DataTypes.STRING,
field: 'last_name'
},
email: {
type: DataTypes.STRING,
isEmail: true,
unique: true
},
password: DataTypes.STRING,
organizationId: {
type: DataTypes.INTEGER,
field: 'organization_id',
allowNull: true
}
}, {
freezeTableName: true,
classMethods: {
generateHash: function(password) {
return bcrypt.hashSync(password, bcrypt.genSaltSync(8), null);
},
associate: function(db) {
User.belongsTo(db.Organization, {foreignKey: 'organizationId'});
},
},
instanceMethods: {
validPassword: function(password) {
return bcrypt.compareSync(password, this.password);
},
},
});
return User;
}
Organization model (organization.js):
module.exports = function(sequelize, DataTypes) {
var Organization = sequelize.define('organization', {
organizationId: {
type: DataTypes.INTEGER,
field: 'organization_id',
autoIncrement: true,
primaryKey: true
},
organizationName: {
type: DataTypes.STRING,
field: 'organization_name'
},
admin: DataTypes.STRING,
members: DataTypes.STRING
},{
freezeTableName: true
});
return Organization;
}
index for tables to connect (db-index.js):
var Sequelize = require('sequelize');
var path = require('path');
var config = require(path.resolve(__dirname, '..', '..','./config/config.js'));
var sequelize = new Sequelize(config.database, config.username, config.password, {
host:'localhost',
port:'3306',
dialect: 'mysql'
});
sequelize.authenticate().then(function(err) {
if (!!err) {
console.log('Unable to connect to the database:', err)
} else {
console.log('Connection has been established successfully.')
}
});
var db = {}
db.Organization = sequelize.import(__dirname + "/organization");
db.User = sequelize.import(__dirname + "/user");
db.Records = sequelize.import(__dirname + "/records");
db.User.associate(db);
db.Records.associate(db);
db.sequelize = sequelize;
db.Sequelize = Sequelize;
sequelize.sync();
module.exports = db;
Are of a route call that triggers this error:
appRoutes.route('/sign-up/organization')
.get(function(req, res){
models.User.find({
where: {
user_id: req.user.email
}, attributes: [ 'user_id', 'email'
]
}).then(function(user){
res.render('pages/sign-up-organization.hbs',{
user: req.user
});
})
})
.post(function(req, res, user){
models.Organization.create({
organizationName: req.body.organizationName,
admin: req.body.admin,
user: {
organizationId: req.body.organizationId
}
}, { include: [models.User] }).then(function(){
console.log(user.user_id);
res.redirect('/app');
}).catch(function(error){
res.send(error);
console.log('Error at Post');
})
});
You need to set up the reverse of the association, Organization hasMany Users

How can i get the full related model in view in sails.js?

I've created a sails.js application.
I'm trying to get full related model Creator in view but I get only id...
How can I do this?
I'm doing this:
Model Author.js
module.exports = {
attributes: {
name: {
type: 'string',
required: true
},
description: {
type: 'string'
},
history: {
type: 'string'
},
creator: {
model: 'User'
}
}
};
model User.js
module.exports = {
attributes: {
name: {
type: 'string',
required: true
},
email: {
type: 'string',
email: true,
required: true,
unique: true
}
authors: {
collection: 'Author',
via: 'creator'
},
...
}
};
AuthorController:
show: function(req, res, next) {
Author.findOne(req.param('id'), function foundAuthor(err, author) {
console.log(author.creator);
res.view({
author: author,
});
});
}
and in my view author/show.ejs
<div class="container">
<h1><%= author.name %></h1>
<h3><%= author.creator %></h3>
<h3><%= author.creator.name %></h3>
</div>
author.creator.name is undefined
and author.creator is id
How can I get full model user instead id in author view?
you need to tell sails to populate the creator
show: function(req, res, next) {
Author.findOne(req.param('id').populate('creator').exec(function foundAuthor(err, author) {
console.log(author.creator);
res.view({
author: author,
});
});
}