i'm using NodeJS & Sequelize for a school project and i'm struggling on making associations w/ sequelize work. I tried a couple of things before but nothing that made my day.
Basically the thing is that a user can have several playlists (hasMany).
And a playlist belongs to a user (belongsTo).
My error is:
Association with alias "playlist" does not exist on users
Here are my models:
/* USER MODEL */
const Sequelize = require('sequelize');
const { db } = require('../utils/db');
const User = db.define('users', {
id: {
allowNull: false,
autoIncrement: true,
primaryKey: true,
type: Sequelize.INTEGER,
},
userID: {
type: Sequelize.INTEGER,
allowNull: false,
field: 'user_id',
},
firstName: {
type: Sequelize.STRING,
field: 'first_name',
allowNull: false,
},
}, {
underscored: true,
tableName: 'users',
freezeTableName: true, // Model tableName will be the same as the model name
});
module.exports = {
User,
};
/* PLAYLIST MODEL */
const sequelize = require('sequelize');
const { db } = require('../utils/db');
const Playlist = db.define('playlist', {
id: {
allowNull: false,
autoIncrement: true,
primaryKey: true,
type: sequelize.INTEGER,
},
name: {
type: sequelize.STRING,
field: 'name',
allowNull: false,
},
coverUrl: {
type: sequelize.STRING,
field: 'cover_url',
allowNull: true,
},
ownerId: {
type: sequelize.INTEGER,
allowNull: false,
references: {
model: 'users',
key: 'user_id',
},
},
}, {
underscored: true,
tableName: 'playlist',
freezeTableName: true,
});
module.exports = {
Playlist,
};
Here is how i load my models:
const { Credentials } = require('./credentials');
const { User } = require('./users');
const { Playlist } = require('./playlist');
function loadModels() {
User.associate = (models) => {
User.hasMany(models.Playlist, { as: 'playlist' });
};
Playlist.associate = (models) => {
Playlist.belongsTo(models.User, { foreignKey: 'owner_id', as: 'owner' });
};
Credentials.sync({ force: false });
User.sync({ force: false });
Playlist.sync({ force: false });
}
module.exports = {
loadModels,
};
And finally here is my query where i get this error:
const express = require('express');
const { auth } = require('../../middlewares/auth');
const { Playlist } = require('../../models/playlist');
const { User } = require('../../models/users');
const router = express.Router();
router.get('/playlist', [], auth, (req, res) => {
User.findOne({
where: { userID: req.user.user_id }, include: 'playlist',
}).then((r) => {
console.log(r);
});
});
module.exports = router;
I'm trying to get all the playlist that belongs to a user.
I removed all the useless code (jwt check etc..)
So when i'm doing a get request on /playlist I get:
Unhandled rejection Error: Association with alias "playlist" does not exist on users.
I understand the error but don't understand why i get this.
What did I miss, any ideas ?
Thanks,
I finally fixed it by re-make all my models and definitions with migrations.
I had the same problem and the solution was that Sequelize pluralize the models name so in my case "playlist" does not exist on users because Sequelize pluralized my model so I had to put "Playlists" instead.
Related
I have this already created two tables called User and Profile.
This is how my model for User looks like..
const Sequelize = require("sequelize");
const db = require("../db");
const User = db.define("User", {
id: {
type: Sequelize.INTEGER,
primaryKey: true,
autoIncrement: true,
},
name: {
type: Sequelize.STRING,
allowNull: true,
},
email: {
type: Sequelize.STRING,
allowNull: false,
unique: true,
validator: {
isEmail: true,
},
},
});
module.exports = User;
and model for Profile looks like..
const Sequelize = require("sequelize");
const User = require("./User");
const db = require("../db");
const Profile = db.define("Profile", {
image: {
type: Sequelize.STRING,
},
description: {
type: Sequelize.TEXT,
},
});
module.exports = Profile;
Now I want to define a one-to-one relationship between User and Profile such that user will recieve a profileId column.
so i am defining it like this
Profile.hasOne(User, {
foreignKey: {
allowNull: false,
},
});
User.belongsTo(Profile);
Now i am not able to figure out how to write migrations for the newly added foreign key
can anyone help me please..
Thanks.
I got the answer. for someone who is confused like me here is the answer
since the User table already exists, migrations for the foreignkey will look like this
module.exports = {
async up(queryInterface, Sequelize) {
return await queryInterface.addColumn("Users", "ProfileId", {
type: Sequelize.INTEGER,
references: {
model: "Profiles",
key: "id",
},
});
},
async down(queryInterface, Sequelize) {
return await queryInterface.removeColumn("Users", "ProfileId", {
type: Sequelize.INTEGER,
references: {
model: "Profiles",
key: "id",
},
});
},
};
the Users in addColumn and removeColumn is the name of the table in which foreignkey was added.
the ProfileId is the name for foreignkey which you would have specified in hasOne.
hope this helps..
I have 2 tables, users and users_signature where the signature takes several applications and I need to make a select according to the application.
Models:
user
const { INTEGER } = require('sequelize');
const Sequelize = require('sequelize');
const database = require('../../config/db');
const User_has_signature = require('./user_has_signature');
const Usuario = database.define('usuario', {
usu_id: {
type: Sequelize.INTEGER,
autoIncrement: true,
allowNull: false,
primaryKey: true
},
usu_rg: {
type: Sequelize.STRING,
},
},
{
freezeTableName: true,
createdAt: false,
updatedAt: false,
});
User.hasMany(User_has_signature, {as: 'user_has_signature'});
module.exports = User;
User_has_signature
const { INTEGER } = require('sequelize');
const Sequelize = require('sequelize');
const database = require('../../config/db');
const User_has_signature = database.define('user_has_signature', {
usu_has_signature_id: {
type: Sequelize.INTEGER,
autoIncrement: true,
allowNull: false,
primaryKey: true
},
user_usu_id: {
type: Sequelize.STRING,
},
signature_aplicativo_signature_aplicativo_id: {
type: Sequelize.STRING,
},
signature_type_signature_type_id: {
type: Sequelize.STRING,
},
},
{
freezeTableName: true,
createdAt: false,
updatedAt: false,
});
User_has_signature.associate = (models) => {
User_has_signature.belongsTo(models.User,
{ foreignKey: 'user_usu_id', as: 'users' });
};
module.exports = User_has_signature;
Controller
UserController
const User = require("../../model/user/user")
const User_has_signature = require("../../model/user/user_has_signature")
async index(req, res){
const user = await User.findAll({
include: [{
model: User_has_signature,
foreignKey: 'user_usu_id',
through: {
where: {signature_ttype_signature_type_id: 3}
}
}]
})
res.status(200).json(user)
return
}
The error that is returning to me in the terminal is: (node:15168)
UnhandledPromiseRejectionWarning: SequelizeEagerLoadingError:
user_has_signature is associated to usuario using an alias. You must
use the 'as' keyword to specify the alias within your include
statement
I think you have to specify the alias you have given when writing your query :
include: [{
model: User_has_signature,
foreignKey: 'user_usu_id',
as : 'users'
through: {
where: {signature_ttype_signature_type_id: 3}
}]
Either way I'm using Sequelize more in Typescript, so I'm not sure of the syntax.
The way it handles One to Many relationship isn't the clearest I've seen (Like Symfony or Spring)
I have connected my app to an existing database. The database table currently has 3 entries but, when I query the model using findAll only an empty array is returned. Im not sure if this has something to do with the database already and existing and connecting to it through models. I am also syncing all files in the index file in the models directory.
//Courses Model for sequelize
const Sequelize = require('sequelize');
module.exports = (sequelize) => {
class Courses extends Sequelize.Model{}
Courses.init({
id: {
type: Sequelize.INTEGER,
primaryKey: true,
autoIncrement: true
},
title: {
type: Sequelize.STRING,
allowNull: false
},
description: {
type: Sequelize.TEXT,
allowNull: false
},
estimatedTime: {
type: Sequelize.STRING,
},
materialsNeeded: {
type: Sequelize.STRING,
},
createdAt: {
type: Sequelize.DATE,
allowNull: false
},
updatedAt: {
type: Sequelize.DATE,
allowNull: false
},
userId: {
type: Sequelize.INTEGER,
references: { model: 'users', key: 'id' },
onDelete: 'CASCADE',
allowNull: false
}
}, {sequelize, modelName: 'courses'});
Courses.associate = (models) => {
models.courses.belongsTo(models.users, {foreignKey: "userId"});
};
return Courses
}
// Router with findAll query
const router = require('express').Router();
const db = require('../models/');
router.get('/', async(req, res) => {
try {
console.log(await db.courses.findAll());
} catch(err) {
console.error(err);
}
res.json({msg: "None"})
});
module.exports = router;
[This is the courses table currently][1]
[1]: https://i.stack.imgur.com/2KkK6.png
This is javascript level issuse I guess. You can't use await statement like that. Please try this out first.
onst router = require('express').Router();
const db = require('../models/');
router.get('/', async (req, res) => {
try {
const courese = await db.courses.findAll()
console.log(courses)
res.send({ courses })
} catch(err) {
console.error(err);
}
res.json({msg: "None"})
});
module.exports = router;
If the problem remains after running this, check if your config is pointing right database.
For checking whether this is problem.
Change your config to point existing database
Run the code
Change your config to point local database with different schema
Do the sequelize sync
Run the code
By doing so, you can check what is the real problem in your code.
Hi everyone I'm having an error "Error: Text.belongsTo called with something that's not a subclass of Sequelize.Model" when I add association of Sequelize in my model it called an error that what I call is not Sequelize Model.
Here is the code of my models, I try to create an association between Post model and Text model.
./Post.js
const { DataTypes } = require('sequelize');
const sequelize = require('../../db/sequelize.setup');
const Text = require('./Text');
const Post = sequelize.define(
'Post',
{
id: {
type: DataTypes.INTEGER,
autoIncrement: true,
primaryKey: true,
allowNull: false,
},
title: {
type: DataTypes.STRING(),
allowNull: false,
},
tags: {
type: DataTypes.ARRAY(DataTypes.INTEGER),
allowNull: true,
},
items: {
type: DataTypes.ARRAY(DataTypes.INTEGER),
allowNull: false,
},
author: {
type: DataTypes.INTEGER,
},
},
{
modelName: 'Post',
timestamps: true,
}
);
Post.hasMany(Text, {
as: 'Text',
foreignKey: 'post_id',
sourceKey: 'id',
});
module.exports = Post;
./Text.js
const { DataTypes } = require('sequelize');
const sequelize = require('../../db/sequelize.setup');
const Post = require('./Post');
const Text = sequelize.define(
'Text',
{
id: {
type: DataTypes.INTEGER,
autoIncrement: true,
primaryKey: true,
allowNull: false,
},
text: {
type: DataTypes.STRING(),
allowNull: false,
},
},
{
modelName: 'Text',
timestamps: true,
}
);
Text.belongsTo(Post, { as: 'Post', foreignKey: 'post_id', targetKey: 'id' });
module.exports = Text;
try to make an index.js file in your models folder and inside of it make your association like this
const db = {};
db.Sequelize = Sequelize;
db.sequelize = sequelize;
db.posts=require("./post.js")(sequlize,sequlize);
db.texts=require....
db.posts.hasMany(db.texts, { foreignKey: 'postId' });
db.texts.belongsTo(db.posts, { foreignKey: 'postId' });
and put the postId in text.js model
I'm building an app in express and I'm using postgres and sequelize for ORM. I have two models, User and Post.
In my user.js and post.js files I have:
module.exports = function(sequelize, DataTypes) {
return sequelize.define('users', {
id: {
type: DataTypes.INTEGER,
allowNull: false,
primaryKey: true,
autoIncrement: true
},
name: {
type: DataTypes.STRING,
allowNull: false,
defaultValue: ""
},
module.exports = function(sequelize, DataTypes) {
return sequelize.define('posts', {
id: {
type: DataTypes.INTEGER,
allowNull: false,
primaryKey: true,
autoIncrement: true
},
user_id: {
type: DataTypes.INTEGER,
allowNull: true
},
title: {
type: DataTypes.STRING,
allowNull: false,
defaultValue: ""
},
I imported those two models and I made the following associations:
User.hasMany(Post, { foreignKey: 'user_id' });
Post.belongsTo(User, { foreignKey: 'user_id' });
I am trying to render all the posts done by a user, but I'm probably missing something.
In my routes I can get the correct user but I don't know how to proceed.
router.route('/:id').get(async (req, res) => {
const user = await User.findById(req.params.id);
console.log(user);
res.send(user);
})
Thanks!
findById does not support the associated model ,
User.findById(req.params.id);
You can change findById to findOne and include model like this ,
User.findOne({
where : { id : req.params.id },
include : {
model : Post
}
});