I have two tables: Books and Articles with a many-to-many relationship between them. Joining table is BookArticles.
models/books.js
module.exports = function(sequelize, DataTypes) { return Food = sequelize.define("Book", { id: { type: DataTypes.INTEGER, primaryKey: true, allowNull: false, autoIncrement: true, unique: true } }); }
models/articles.js
module.exports = function(sequelize, DataTypes) { return Food = sequelize.define("Article", { id: { type: DataTypes.INTEGER, primaryKey: true, allowNull: false, autoIncrement: true, unique: true } }); }
models/bookArticles.js
module.exports = function(sequelize, DataTypes) { return Food = sequelize.define("BookArticles", { id: { type: DataTypes.INTEGER, primaryKey: true, allowNull: false, autoIncrement: true, unique: true }, bookId: { type: DataTypes.INTEGER, references: 'Book', referencesKey: 'id', allowNull: false }, ArticleId: { type: DataTypes.INTEGER, references: 'Article', referencesKey: 'id', allowNull: false }, }); }
And models/index.js
m.BookArticles.belongsTo(m.Book); m.Book.hasMany(m.Article, {through: m.BookArticles}); m.BookArticles.belongsTo(m.Article); m.Article.hasMany(m.Books, {through: m.BookArticles});
but I could not get book articles
How can I get it ??
Creating associations in sequelize is done by calling one of the belongsTo / hasOne / hasMany / belongsToMany functions on a model (the source), and providing another model as the first argument to the function (the target). hasOne - adds a foreign key to the target and singular association mixins to the source.
The A.hasMany(B) association means that a One-To-Many relationship exists between A and B , with the foreign key being defined in the target model ( B ). These three calls will cause Sequelize to automatically add foreign keys to the appropriate models (unless they are already present).
Updated for Sequelize v2/3/4/5
Generally I think the problems are that we are confused about what tables created, and what methods are gained by associations.
Note: Defining foreignKey or cross table name are optional. Sequelize automatically creates it, but defining it allows coders to read the models and find out what the foreign keys/cross table names are, instead of guessing or needing to access the database.
// foreign key has to be defined on both sides. Parent.hasOne(Child, {foreignKey: 'Parent_parentId'}) // "Parent_parentId" column will exist in the "belongsTo" table. Child.belongsTo(Parent, {foreignKey: 'Parent_parentId'})
Parent.hasMany(Child, {foreignKey: 'Parent_parentId'}) Child.belongsTo(Parent, {foreignKey: 'Parent_parentId'})
Parent.belongsToMany( Child, { // this can be string (model name) or a Sequelize Model Object Class // through is compulsory since v2 through: 'Parent_Child', // GOTCHA // note that this is the Parent's Id, not Child. foreignKey: 'Parent_parentId' } ) /* The above reads: "Parents" belongs to many "Children", and is recorded in the "Parent_child" table, using "Parents"'s ID. */ Child.belongsToMany( Parent, { through: 'Parent_Child', // GOTCHA // note that this is the Child's Id, not Parent. foreignKey: 'Child_childId' } )
Why the verbose "Parent_parentId" and not just "parentId"? This is to make it obvious that it's a foreign key that belonged to "Parent". In most cases it's okay to just use the more succinct "parentId".*
DB.Parent.findOne({ where: { id: 1 }, include: [ DB.Child ] }).then(parent => { // you should get `parent.Child` as an array of children. })
Associations give the Data Access Object (DAO) methods:
hasOne():In setting a Parent.hasOne(Child)
, methods available to parent
DAO instance:
DB.Parent.findOne({ where: { id: 1 } }).then(parent => { // `parent` is the DAO // you can use any of the methods below: parent.getChild parent.setChild parent.addChild parent.createChild parent.removeChild parent.hasChild })
hasMany(): In setting a Parent.hasMany(Child)
, methods available to parent
DAO instance:
parent.getChildren, parent.setChildren, parent.addChild, parent.addChildren, parent.createChild, parent.removeChild, parent.hasChild, parent.hasChildren,
belongsTo()/belongsToMany: In setting a Child.belongsTo(Parent)
, methods available to child
DAO instance:
child.getParent, child.setParent, child.createParent, //belongsToMany child.getParents, child.setParents, child.createParents,
// a parent can have many children Parent.belongsToMany(Child, { as: 'Natural', through: 'Parent_Child', foreignKey: 'Parent_parentId' }) // a child must at least have 2 parents (natural mother and father) Child.belongsToMany(Parent, { as: 'Natural', through: 'Parent_Child', foreignKey: 'Child_childId' })
Foster Parents/Children Parent.belongsToMany(Child, { as: 'Foster', through: 'Parent_Child', foreignKey: 'Parent_parentId' }) Child.belongsToMany(Parent, { as: 'Foster', through: 'Parent_Child', foreignKey: 'Child_childId' });
The above will create the Parent_Child
cross table, with NaturalId
and FosterId
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With