Sequelize 1:N no association found - javascript

I have 2 models: User and Foto where each User can have N Fotos and each Foto is assciate with 1 User.
So what i need is to eager load the Foto(i pass a specific id to retrive the foto) and the user associated to that foto.
My User model
"use strict";
var sequelize = require('./index');
var bcrypt = require('bcrypt-nodejs');
var Foto = require('./Foto');
module.exports = function (sequelize, DataTypes) {
var User = sequelize.define("User", {
username: {
type: DataTypes.STRING,
allowNull: false,
unique: true,
validate: {
isUnique: function (value, next) {
var self = this;
User.find({ where: { username: value } })
.then(function (user) {
// reject if a different user wants to use the same username
if (user && self.id !== user.id) {
return next('username already in use!');
}
return next();
})
.catch(function (err) {
return next(err);
});
}
}
},
email: {
type: DataTypes.STRING,
allowNull: false,
unique: true,
validate: {
isUnique: function (value, next) {
var self = this;
User.find({ where: { email: value } })
.then(function (user) {
// reject if a different user wants to use the same email
if (user && self.id !== user.id) {
return next('Email already in use!');
}
return next();
})
.catch(function (err) {
return next(err);
});
}
}
},
typeOfUser: {
type: DataTypes.INTEGER,
allowNull:true,
defaultValue:null
},
country: {
type: DataTypes.STRING,
allowNull:true,
defaultValue:null
},
birthDate:{
type: DataTypes.DATEONLY,
allowNull:true,
defaultValue:null
},
reports: {
type: DataTypes.INTEGER,
defaultValue: 0
},
points: {
type: DataTypes.INTEGER,
defaultValue: 0
},
password: {
type: DataTypes.STRING,
allowNull:false
},
numberFotos: {
type: DataTypes.INTEGER,
defaultValue: 0
}
}, {
classMethods: {
generateHash: function (password) {
return bcrypt.hashSync(password, bcrypt.genSaltSync(8), null);
},
associate: function(models){
User.hasMany(models.Foto,{foreignKey: "userId"});
}
},
instanceMethods: {
validPassword: function (password) {
return bcrypt.compareSync(password, this.password);
}
}
});
return User;
}
important part:
associate: function(models){
User.hasMany(models.Foto,{foreignKey: "userId"});
}
My Foto model:
"use strict";
var sequelize = require('./index');
var bcrypt = require('bcrypt-nodejs');
var User = require('./User');
module.exports = function (sequelize, DataTypes) {
var Foto = sequelize.define("Foto", {
reports: {
type: DataTypes.INTEGER,
defaultValue: 0
},
image: {
type: DataTypes.STRING,
allowNull: false
},
date: {
type: DataTypes.DATE,
allowNull: true
},
lat: {
type: DataTypes.STRING,
allowNull: true
},
lon: {
type: DataTypes.STRING,
allowNull: true
},
altitude: {
type: DataTypes.STRING,
allowNull: true
},
userId: {
type: DataTypes.INTEGER,
allowNull: false
},
plantId: {
type: DataTypes.INTEGER,
allowNull: true
},
},
{
associate: function (models) {
Foto.belongsTo(models.User);
}
}
);
return Foto;
}
important part:
{
associate: function (models) {
Foto.belongsTo(models.User);
}
}
And in my controller i try to eager load like this:
allPictures: function (req, res) {
Foto.findAll({include: [{model: User, as: 'User'}]})
.then(function (fotos) {
res.send(fotos);
})
}

Related

Post request mysql with foreign keys?

I´m trying to create a post request that is suppose to check if the person posting the request is the person logged in and then posts the response. I have a table for the customer and a table for address, I want to make a post request to the address so that when the logged in user inserts an address their id will be stored as a foreign key in the address table. My address table looks like this:
module.exports = (sequelize, DataTypes) => {
const Address = sequelize.define("Address", {
address: {
type: DataTypes.STRING,
allowNull: false,
validate: {
notEmpty: true
}
},
city: {
type: DataTypes.STRING,
allowNull: false,
validate: {
notEmpty: true
}
},
postcode: {
type: DataTypes.STRING,
allowNull: false,
validate: {
notEmpty: true
}
},
country: {
type: DataTypes.STRING,
allowNull: false,
validate: {
notEmpty: true
}
}
});
return Address;
};
and my customer table is like this:
module.exports = (sequelize, DataTypes) => {
const Customers = sequelize.define("Customers", {
firstName: {
type: DataTypes.STRING,
allowNull: false,
validate: {
notEmpty: true
}
},
lastName: {
type: DataTypes.STRING,
allowNull: false,
validate: {
notEmpty: true
}
},
email: {
type: DataTypes.STRING,
allowNull: false,
validate: {
notEmpty: true
}
},
password: {
type: DataTypes.STRING,
allowNull: false,
validate: {
notEmpty: true
}
},
isAdmin: {
type: DataTypes.BOOLEAN,
default: '0',
}
});
Customers.associate = (models) => {
Customers.hasMany(models.Address, {
onDelete: "cascade",
});
Customers.hasMany(models.Orderline, {
onDelete: "cascade",
});
};
return Customers;
};
my post request is like this:
addressRouter.post(
'/:id', isAuth,
expressAsyncHandler( async (req, res) => {
const {id, address, postcode} = req.params;
const customer = await Customers.findOne({where: {id: id}})
const custAddress = await Address.findOne({where: {address,postcode}})
const shippingAddress = {
address: req.body.address,
city: req.body.city,
postcode: req.body.postcode,
country: req.body.country,
}
if (!customer) {
res.status(401).send({
message: "Customer Not Found",
});
}else if(custAddress){
res.status(401).send({
message: "Address already exist",
});
}else{
Address.create(shippingAddress);
res.send({
id: shippingAddress.id,
address: shippingAddress.address,
city: shippingAddress.city,
postcode: shippingAddress.postcode,
country: shippingAddress.country,
});
}
})
please do not mind the isAuth function because that works I was able to update info for user with it. my Api for the post request looks like this:
export const shipping = async({address, city, postcode, country}) => {
try{
const {token} = getCustomerInfo();
const response = await axios({
url: `${apiUrl}/api/${id}`,
method: 'POST',
headers: {
'Content-Type' : 'application/json',
Authorization: `Bearer ${token}`,
},
data:{
address,
city,
postcode,
country,
},
});
if(response.statusText !== 'OK'){
throw new Error(response.data.message);
}
return response.data;
}catch(err){
console.log(err);
return {error: err.response.data.message || err.message};
}
};
Any help is really appreciated.
You need to define an association from 'Address' to Customer:
Address.associate = (models) => {
Address.belongsTo(models.Customer);
};
return Address
and of course indicate customerId in a newly created address:
Address.create(shippingAddress);
res.send({
id: shippingAddress.id,
address: shippingAddress.address,
city: shippingAddress.city,
postcode: shippingAddress.postcode,
country: shippingAddress.country,
customerId: customer.id
});

Create a model with hash password in Sequelize?

I'm trying to create a model in Sequelize with a hash password using bcrypt, and run "sequelize db:migrate" but I can't. I get this error whenever I try to run it. All I need to is have "password" with the hash already done. I don't know where I'm going wrong or what I'm missing. can anybody help me?
== 001-user: migrating =======
ERROR: s.replace is not a function
I'm using: Sequelize: 6.16.2. Database: Postgres. Node: 15. Bcrypt: 5.0.1
Here is my User model:
class User extends Model {
/**
* #param {import("../index")} models
*/
static associate (models) {
User.belongsTo(models.UserRole, { as: "user_role", foreignKey: "id_user_role" });
}
}
/**
* #param {import("sequelize").Sequelize} sequelize Connection with the database
*/
function initUser (sequelize) {
User.init({
id: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true
},
user: DataTypes.STRING(30),
name: DataTypes.STRING(100),
email: DataTypes.STRING(100),
password: DataTypes.STRING(100),
id_user_role: {
type: DataTypes.INTEGER,
references: {
model: sequelize.models.UserRole,
key: "id"
}
},
deleted: DataTypes.BOOLEAN
},
{
sequelize,
timestamps: false,
modelName: "User",
tableName: "user",
underscored: true,
hooks: {
beforeCreate: async (user) => {
if (user.password) {
const salt = await bcrypt.genSaltSync(11, "a");
user.password = bcrypt.hashSync(user.password, salt);
}
},
beforeUpdate: async (user) => {
if (user.password) {
const salt = await bcrypt.genSaltSync(11, "a");
user.password = bcrypt.hashSync(user.password, salt);
}
}
}
});
return User;
}
module.exports = { initUser };
User migration:
module.exports = {
/**
* #param {import("sequelize").QueryInterface} queryInterface
* #param {import("sequelize").DataTypes} Sequelize
*/
up: async (queryInterface, Sequelize) => {
await queryInterface.createTable("user", {
id: {
type: Sequelize.INTEGER,
allowNull: false,
autoIncrement: true,
primaryKey: true
},
user: {
type: Sequelize.STRING(30),
allowNull: false
},
name: {
type: Sequelize.STRING(100),
allowNull: false
},
email: {
type: Sequelize.STRING(100),
allowNull: false
},
password: {
type: Sequelize.STRING(100),
allowNull: false
},
id_user_role: {
type: Sequelize.INTEGER,
allowNull: false,
references: { model: UserRole, key: "id" }
},
deleted: {
type: Sequelize.BOOLEAN,
allowNull: false,
defaultValue: false
}
});
await queryInterface.bulkInsert("user", [
{
user: "admin", name: "test", email: "test#admin.com", password: "admin", id_user_role: 1
},
{
user: "comum", name: "test", email: "test#comum.com", password: "comum", id_user_role: 2
},
{
user: "regular", name: "test", email: "test#regular.com", password: "comum", id_user_role: 3
}
]);
}
};

EagerLoadingError [SequelizeEagerLoadingError]: grl_entidade is not associated to stn_matriz_gerada

I have this error and can`t find a way arround it: EagerLoadingError [SequelizeEagerLoadingError]: grl_entidade is not associated to stn_matriz_gerada!
I have tryed many things, currently this is the way my app is:
stn_matriz_gerada.js
const Sequelize = require('sequelize');
module.exports = function(sequelize, DataTypes) {
return sequelize.define('stn_matriz_gerada', {
conta: {
type: DataTypes.STRING,
allowNull: true,
primaryKey: true
},
v1: {
type: DataTypes.STRING,
allowNull: true
},
t1: {
type: DataTypes.STRING,
allowNull: true
},
v2: {
type: DataTypes.STRING,
allowNull: true
},
t2: {
type: DataTypes.STRING,
allowNull: true
},
v3: {
type: DataTypes.STRING,
allowNull: true
},
t3: {
type: DataTypes.STRING,
allowNull: true
},
v4: {
type: DataTypes.STRING,
allowNull: true
},
t4: {
type: DataTypes.STRING,
allowNull: true
},
v5: {
type: DataTypes.STRING,
allowNull: true
},
t5: {
type: DataTypes.STRING,
allowNull: true
},
v6: {
type: DataTypes.STRING,
allowNull: true
},
t6: {
type: DataTypes.STRING,
allowNull: true
},
v7: {
type: DataTypes.STRING,
allowNull: true
},
t7: {
type: DataTypes.STRING,
allowNull: true
},
valor: {
type: DataTypes.DOUBLE,
allowNull: true
},
tipo: {
type: DataTypes.STRING,
allowNull: true
},
tipo_int: {
type: DataTypes.INTEGER,
allowNull: true
},
natureza_valor: {
type: DataTypes.STRING,
allowNull: true
},
exercicio: {
type: DataTypes.INTEGER,
allowNull: true
},
mes: {
type: DataTypes.INTEGER,
allowNull: true
},
grl_entidade: {
type: DataTypes.INTEGER,
allowNull: true,
references: {
model: 'grl_entidade',
key: 'id'
}
},
conteudo_txt: {
type: DataTypes.TEXT,
allowNull: true
}
}, {
sequelize,
tableName: 'stn_matriz_gerada',
schema: 'public',
timestamps: false
});
};
init-models.js
var DataTypes = require("sequelize").DataTypes;
var _grl_entidade = require("./grl_entidade");
var _grl_entidade_tipo = require("./grl_entidade_tipo");
var _grl_municipio = require("./grl_municipio");
var _grl_uf = require("./grl_uf");
var _stn_matriz_gerada = require("./stn_matriz_gerada");
function initModels(sequelize) {
var grl_entidade = _grl_entidade(sequelize, DataTypes);
var grl_entidade_tipo = _grl_entidade_tipo(sequelize, DataTypes);
var grl_municipio = _grl_municipio(sequelize, DataTypes);
var grl_uf = _grl_uf(sequelize, DataTypes);
var stn_matriz_gerada = _stn_matriz_gerada(sequelize, DataTypes);
grl_entidade_tipo.hasMany(grl_entidade,
{ foreignKey: { name: "grl_entidade_tipo"},
as: "grl_entidade_tipo_fk"},);
grl_entidade.belongsTo(grl_entidade_tipo,
{ foreignKey: { name: "grl_entidade_tipo"},
as: "grl_entidade_tipo_fk"},);
grl_municipio.hasMany(grl_entidade,
{ foreignKey: { name: "grl_municipio"},
as: "grl_municipio_fk"},);
grl_entidade.belongsTo(grl_municipio,
{ foreignKey: { name: "grl_municipio"},
as: "grl_municipio_fk"},);
grl_uf.hasMany(grl_municipio,
{ foreignKey: { name: "grl_uf"},
as: "grl_uf_fk"},);
grl_municipio.belongsTo(grl_uf,
{ foreignKey: { name: "grl_uf"},
as: "grl_uf_fk"},);
grl_entidade.hasMany(stn_matriz_gerada,
{ foreignKey: { name: "grl_entidade"},
as: "grl_entidade_fk"},);
stn_matriz_gerada.belongsTo(grl_entidade,
{ foreignKey: { name: "grl_entidade"},
as: "grl_entidade_fk"},);
return {
grl_entidade,
grl_entidade_tipo,
grl_municipio,
grl_uf,
stn_matriz_gerada,
};
}
module.exports = initModels;
module.exports.initModels = initModels;
module.exports.default = initModels;
MscService.js
class MscService {
static async getAllMscs() {
try {
return await database.stn_matriz_gerada.findAll();
} catch (error) {
throw error;
}
}
static async getAMsc(conta) {
try {
const theMsc = await database.stn_matriz_gerada.findAll({
where: { conta: Number(conta) },
include: [ {model: database.grl_entidade, as: 'grl_entidade_fk' }]
});
return theMsc;
} catch (error) {
console.log(error);
throw error;
}
}
}
export default MscService;
It has hasMany and belongsTo but stills give me the error of EagerLoadingError [SequelizeEagerLoadingError]: grl_entidade is not associated to stn_matriz_gerada!
Version: "sequelize": "^6.3.5",
Can anyone help me please?

Query sequelize table without column 'id'

I have the following model
(Migration) transaction.js
'use strict';
module.exports = {
up: function(queryInterface, Sequelize) {
return queryInterface.createTable('transactions', {
date: {
type: Sequelize.DATEONLY
},
transNo: {
type: Sequelize.INTEGER,
allowNull: false,
autoIncrement: true,
primaryKey: true,
},
accNo: {
type: Sequelize.INTEGER
},
createdAt: {
allowNull: false,
type: Sequelize.DATE
},
updatedAt: {
allowNull: false,
type: Sequelize.DATE
}
});
},
down: function(queryInterface, Sequelize) {
return queryInterface.dropTable('transactions');
}
};
(Model) transaction.js
'use strict';
const credit = require('./credit.js');
module.exports = function(sequelize, DataTypes) {
var transaction = sequelize.define('transaction', {
date: DataTypes.DATEONLY,
transNo: DataTypes.INTEGER,
accNo: DataTypes.INTEGER
}, {
classMethods: {
associate: function(models) {
// associations can be defined here
transaction.hasOne(models.credit, {foreignKey: 'transNo'});
}
}
});
return transaction;
};
(Model) credit.js
module.exports = function(sequelize, DataTypes) {
var credit = sequelize.define('credit', {
transNo: DataTypes.INTEGER,
creNo: DataTypes.INTEGER
}, {
classMethods: {
associate: function(models) {
// associations can be defined here
}
}
});
return credit;
};
(Migration) credit.js
` module.exports = {
up: function(queryInterface, Sequelize) {
return queryInterface.createTable('credits', {
transNo: {
type: Sequelize.INTEGER
},
creNo: {
type: Sequelize.INTEGER,
autoIncrement: true,
allowNull: false,
primaryKey: true
},
createdAt: {
allowNull: false,
type: Sequelize.DATE
},
updatedAt: {
allowNull: false,
type: Sequelize.DATE
}
});
},
down: function(queryInterface, Sequelize) {
return queryInterface.dropTable('credits');
}
};`
it still queries with the id column
Executing (default): SELECT transaction.id, transaction.date, transaction.accNo,.........(and so on).
how to disable the id column from being queried?
You simply need to set another column as your primary key and the id column won't be generated by default.
module.exports = function(sequelize, DataTypes) {
var credit = sequelize.define('credit', {
transNo: DataTypes.INTEGER,
{
creNo: DataTypes.INTEGER,
primaryKey: true //define a primaryKey
}
}, {
classMethods: {
associate: function(models) {
// associations can be defined here
}
}
});
return credit;
};

Graphql: Query returns null for all fields except ID

When I run the following Query:
{
viewer {
id
firstName
lastName
}
}
I get the following object which displays the incorrect query results:
{
"data": {
"viewer": {
"id": "VXNlcjo=",
"firstName": null,
"lastName": null
}
}
}
I have set up the following database.js:
import Sequelize from 'sequelize';
import bcrypt from 'bcrypt';
// Create a Sequelize instance
var connection = new Sequelize('dev', 'mary', 'password', {
host: 'localhost',
dialect: 'postgres',
pool: {
max: 5,
min: 0,
idle: 10000
}
});
// User model
var User = connection.define('user', {
// First name
firstName: {
type: Sequelize.STRING,
allowNull: false,
validate: {
is: {
args: /^[a-z]+$/i,
msg: 'First name is invalid'
}
}
},
// Last name
lastName: {
type: Sequelize.STRING,
allowNull: false,
validate: {
is: {
args: /^[a-z]+$/i,
msg: 'Last name is invalid'
}
}
},
// Username
username: {
type: Sequelize.STRING,
allowNull: false,
unique: true,
validate: {
is: {
args: /^#?(\w){3,15}$/,
msg: 'Username can not exceed 15 characters or contain spaces.'
}
}
},
// Email
email: {
type: Sequelize.STRING,
allowNull: false,
unique: true,
validate: {
isEmail: true
}
},
// Password
password: {
type: Sequelize.STRING,
allowNull: false,
unique: true,
validate: {
// Validate Password
}
}
}, {
// Use plural names in database.
freezeTableName: false,
// Timestamps
timestamps: true,
// hooks
hooks: {
afterValidate: user => {
user.password = bcrypt.hashSync(user.password, 8);
}
}
});
// Group model
var Group = connection.define('group', {
// Owner Id
ownerId: {
type: Sequelize.INTEGER,
allowNull: false
},
// Group name
name: {
type: Sequelize.STRING,
allowNull: false
},
// Domain
domain: {
type: Sequelize.STRING,
allowNull: false
},
// Topic
topic: {
type: Sequelize.STRING,
validate: {
len: {
args: [0, 150],
msg: 'Topic can not exceed 150 characters.'
}
}
},
// Access
private: {
type: Sequelize.BOOLEAN
},
// Password
password: {
type: Sequelize.STRING,
defaultValue: null,
validate: {
// Validate Password
}
}
}, {
freezeTableName: false,
// Timestamps
timestamps: true,
// hooks
hooks: {
afterValidate: user => {
if (user.password) {
user.password = bcrypt.hashSync(user.password, 8);
}
}
}
});
// Relationships
User.belongsToMany(Group, { through: 'UserGroup' });
Group.belongsToMany(User, { through: 'UserGroup' });
// Insert some data by calling sync
connection.sync({
force: true
}).then ( () => {
// First user dummy
User.create( {
firstName: 'Sam',
lastName: 'Smith',
username: 'samsmith',
email: 'samsith#some.com',
password: 'somepassword'
})
.then(user => {
user.createGroup({
ownerId: user.id,
name: 'Engineering',
topic: 'A group',
domain: user.email.split('#')[1],
private: true,
password: ''
});
});
// Second user dummy
User.create( {
firstName: 'Sam',
lastName: 'Joshua',
username: 'samjoshua',
email: 'samjoshua#gmail.com',
password: 'somepassword'
})
.then(user => {
user.createGroup({
ownerId: user.id,
name: 'Design',
topic: 'This is some group',
domain: user.email.split('#')[1],
private: false,
password: ''
});
});
})
.catch(error => {
console.log(error);
});
export default connection;
and the following schema.js file:
import {
GraphQLBoolean,
GraphQLFloat,
GraphQLID,
GraphQLInt,
GraphQLList,
GraphQLNonNull,
GraphQLObjectType,
GraphQLSchema,
GraphQLString,
} from 'graphql';
import {
connectionArgs,
connectionDefinitions,
connectionFromArray,
fromGlobalId,
globalIdField,
mutationWithClientMutationId,
nodeDefinitions,
} from 'graphql-relay';
import db from './database';
/**
* We get the node interface and field from the Relay library.
*
* The first method defines the way we resolve an ID to its object.
* The second defines the way we resolve an object to its GraphQL type.
*/
var {nodeInterface, nodeField} = nodeDefinitions(
(globalId) => {
var {type, id} = fromGlobalId(globalId);
if (type === 'User') {
return db.models.user.getUser(id);
} else if (type === 'Group') {
return db.models.group.getGroup(id);
} else {
return null;
}
},
(obj) => {
if (obj instanceof User) {
return userType;
} else if (obj instanceof Group) {
return groupType;
} else {
return null;
}
}
);
/**
* We define our own types here.
*/
var userType = new GraphQLObjectType({
name: 'User',
description: 'A person who users our app',
fields: () => ({
id: globalIdField('User'),
firstName: {
type: GraphQLString,
description: 'A users first name',
resolve(user) {
return user.firstName;
}
},
lastName: {
type: GraphQLString,
resolve(user) {
return user.lastName;
}
},
username: {
type: GraphQLString,
resolve(user) {
return user.username;
}
},
email: {
type: GraphQLString,
resolve(user) {
return user.email;
}
},
groups: {
type: new GraphQLList(groupType),
resolve(user) {
return user.getGroups();
}
},
}),
interfaces: [nodeInterface],
});
// Group query
var groupType = new GraphQLObjectType({
name: 'Group',
description: 'A users group',
fields: () => ({
id: globalIdField('Group'),
ownerId: {
type: GraphQLInt,
resolve(group) {
return group.ownerId;
}
},
name: {
type: GraphQLString,
resolve(group) {
return group.name;
}
},
topic: {
type: GraphQLString,
resolve(group) {
return group.topic;
}
},
domain: {
type: GraphQLString,
resolve(group) {
return group.domain;
}
},
private: {
type: GraphQLBoolean,
resolve(group) {
return group.private;
}
},
users: {
type: new GraphQLList(userType),
resolve(group) {
return group.getUsers();
}
}
}),
interfaces: [nodeInterface],
});
/**
* This is the type that will be the root of our query,
* and the entry point into our schema.
*/
var queryType = new GraphQLObjectType({
name: 'Query',
description: 'This is the root query',
fields: () => ({
node: nodeField,
// Add our own root fields here
viewer: {
type: userType,
args: {
id: {
type: GraphQLInt
},
email: {
type: GraphQLString
}
},
resolve: (root, args) => {
return db.models.user.findAll({ where: args });
}
},
}),
});
/**
* This is the type that will be the root of our mutations,
* and the entry point into performing writes in our schema.
*/
var mutationType = new GraphQLObjectType({
name: 'Mutation',
description: 'Data insertion',
fields: () => ({
addUser: {
type: userType,
args: {
firstName: {
type: new GraphQLNonNull(GraphQLString),
},
lastName: {
type: new GraphQLNonNull(GraphQLString),
},
username: {
type: new GraphQLNonNull(GraphQLString),
},
email: {
type: new GraphQLNonNull(GraphQLString),
},
password: {
type: new GraphQLNonNull(GraphQLString),
}
},
resolve(_, args) {
return Db.models.user.create({
firstName: args.firstName,
lastName: args.lastName,
username: args.username,
email: args.email.toLowerCase(),
password: args.password
});
}
}
})
});
/**
* Finally, we construct our schema (whose starting query type is the query
* type we defined above) and export it.
*/
export var Schema = new GraphQLSchema({
query: queryType,
mutation: mutationType
});
I can't seem to find where I have made a mistake. The database file seems fine since I can see the data in the dev table so I guess my error is somewhere in the schema.js file. Thank you for the help.

Categories