Nuestros mejores desarrolladores han agotado sus provisiones de café, en su búsqueda a tiempo completo por la respuesta, hasta que Fernando halló la contestación en Gitea así que hoy la comparte con nosotros.
Solución:
Sequelize Association Cheatsheet
Actualizado para Sequelize v2/3/4/5
En general, creo que los problemas son que estamos confundidos acerca de qué tablas se crearon y qué métodos se obtienen mediante asociaciones.
Nota: La definición de ForeignKey o el nombre de la tabla cruzada es opcional. Sequelize lo crea automáticamente, pero definirlo permite a los codificadores leer los modelos y descubrir qué es lo extraño. keys/los nombres de las tablas cruzadas son, en lugar de adivinar o necesitar acceder a la base de datos.
TLDR;
O:O
// 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')
O:M
Parent.hasMany(Child, foreignKey: 'Parent_parentId')
Child.belongsTo(Parent, foreignKey: 'Parent_parentId')
NUEVO MÉJICO
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'
)
¿Por qué el detallado “Parent_parentId” y no solo “parentId”? Esto es para que sea obvio que es un extranjero. key que pertenecía a “Padre”. En la mayoría de los casos, está bien usar el “parentId” más sucinto.*
Las asociaciones le brindan 2 funcionalidades: (1) carga ansiosa y (2) métodos DAO:
1. Incluir (carga ansiosa)
DB.Parent.findOne(
where: id: 1 ,
include: [ DB.Child ]
).then(parent =>
// you should get `parent.Child` as an array of children.
)
2. Métodos ganados por hasOne(), hasMany() y proudTo()/belongsToMany()
Las asociaciones dan los métodos del objeto de acceso a datos (DAO):
Tiene uno():
Al establecer un Parent.hasOne(Child)
métodos disponibles para parent
instancia DAO:
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
)
tiene muchas():
Al establecer un Parent.hasMany(Child)
métodos disponibles para parent
instancia DAO:
parent.getChildren,
parent.setChildren,
parent.addChild,
parent.addChildren,
parent.createChild,
parent.removeChild,
parent.hasChild,
parent.hasChildren,
pertenece a()/perteneceamuchos:
Al establecer un Child.belongsTo(Parent)
métodos disponibles para child
instancia DAO:
child.getParent,
child.setParent,
child.createParent,
//belongsToMany
child.getParents,
child.setParents,
child.createParents,
También puedes tener varias relaciones.
Padres Naturales/Hijos
// 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'
)
Padres adoptivos/niños
Parent.belongsToMany(Child,
as: 'Foster',
through: 'Parent_Child',
foreignKey: 'Parent_parentId'
)
Child.belongsToMany(Parent,
as: 'Foster',
through: 'Parent_Child',
foreignKey: 'Child_childId'
);
Lo anterior creará el Parent_Child
mesa cruzada, con NaturalId
y FosterId
.
elimine el modelo BookArticles y actualice la relación con:
m.Book.hasMany(m.Article, through: 'book_articles');
m.Article.hasMany(m.Books, through: 'book_articles');
Así es como resolví el problema similar. Tenía dos modelos, un modelo de usuario.
var user = sequelize.define('user',
name:
Sequelize.STRING(255)
,
email:
type: Sequelize.STRING(255),
unique: true,
validate:
isEmail: true
);
y un modelo a seguir
var Role = sequelize.define('role',
name:
Sequelize.ENUM('ER', 'ALL', 'DL')
,
description:
type: Sequelize.TEXT
);
Luego creé el modelo de unión UserRole
var UserRole = sequelize.define('user_role',
id:
type: Sequelize.INTEGER,
primaryKey: true,
autoIncrement: true
,
name:
type: Sequelize.ENUM('Admin', 'Staff', 'Customer', 'Owner')
);
Nota: debe definir explícitamente la identificación para UserRole; de lo contrario, la secuenciación utilizará los dos foráneos keys en este caso user_id
y role_id
como tu principal keys.
Luego creé la relación pertenece a muchos de la siguiente manera
User.belongsToMany(Role, as: 'Roles', through: model: UserRole, unique: false , foreignKey: 'user_id' );
Role.belongsToMany(User, as: 'Users', through: model: UserRole, unique: false , foreignKey: 'role_id' );
Reseñas y calificaciones
Si haces scroll puedes encontrar las explicaciones de otros usuarios, tú también tienes el poder dejar el tuyo si te apetece.