web-dev-qa-db-fra.com

Comment implémenter une association plusieurs à plusieurs dans la suite

J'ai deux tableaux: des livres et des articles avec une relation plusieurs-à-plusieurs entre eux. La table de jonction est 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
    },
  });
}

Et 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});

mais je n'ai pas pu obtenir d'articles de livre

Comment puis-je l'avoir ??

35
Anuj

Update 17 Feb 15: 1. La nouvelle v2 utilise 2x .belongsToMany() pour N: M.

La compréhension de toutes ces associations a posé de nombreux problèmes.

En général, je pense que nous sommes confus quant à ce que sont les tables créées et quelles méthodes sont gagnées par les associations.

Le texte ci-dessous est quelque chose que j'ai écrit pour normaliser la façon dont je veux que mon équipe gère tout cela. Quant aux conventions de dénomination, vous pouvez l'ignorer si vous laissez simplement Sequelize tout par défaut.

Cependant, il est recommandé de nommer explicitement vos conventions pour de nombreuses raisons.

Bref:

O: O, configurez une Parent.hasOne(Child) ET Child.belongsTo(Parent).

O: M, configurez Parent.hasMany(Child) ET Child.belongsTo(Parent).

N: M *, configurez Parent.belongsToMany(Child, {through: 'Parent_Child', foreignKey: 'Parent_rowId'}) et Child.belongsToMany(Parent, {through: 'Parent_Child', foreignKey: 'Child_rowId'}).

Méthodes gagnées par hasOne (), hasMany () et appartientTo ()/appartientToMany ()

Pour comprendre pourquoi nous faisons les associations ci-dessus, nous commençons par savoir quelles sont les méthodes que nous gagnons pour chaque modèle.

en a un():

Lors de la définition d'une Parent.hasOne(Child), méthodes disponibles pour parent instance DAO:

parent.getChild,
parent.setChild,
parent.addChild,
parent.createChild,
parent.removeChild,
parent.hasChild

a beaucoup():

Lors de la définition d'une Parent.hasMany(Child), méthodes disponibles pour parent instance DAO:

parent.getChildren,
parent.setChildren,
parent.addChild,
parent.createChild,
parent.removeChild,
parent.hasChild,
parent.hasChildren

appartient à ()/appartient à beaucoup:

Lors de la définition d'une Child.belongsTo(Parent), méthodes disponibles pour child instance DAO:

child.getParent,
child.setParent,
child.createParent

//belongsToMany
child.getParents,
child.setParents,
child.createParents

Syntaxe de configuration des relations. Et nos conventions

Pour O: O et O: M:

Parent.hasOne(Child, {foreignKey: 'Parent_childID'});
Child.belongsTo(Parent, {foreignKey: 'Parent_childID'});

Notez que nous avons explicitement défini nos ForeignKeys comme Parent_childID. C'est parce que nous voulons cette convention PascalCase_camelCase pour TableName_keyName.

Relation plusieurs à plusieurs

Pour une relation N: M, procédez comme suit:

Parent.belongsToMany( Child, {
    as: [Relationship],
    through: [Parent_Child] //this can be string or a model,
    foreignKey: 'Parent_rowId'
});

Child.belongsToMany(Parent, {
    as: [Relationship2],
    through: [Parent_Child],
    foreignKey: 'Child_rowId'
});

*New in v2: L'utilisation de "à travers" est désormais indispensable. En standard, en utilisant le paramètre "through", nous définissons explicitement tous les noms de tableau croisé pour la cohérence et moins de pièges.

Ce qui précède créera Parent_Child, avec RelationshipId et Relationship2ID.

Sequelize peut créer des clés étrangères automatiquement, mais je définis généralement les miennes.

Conventions de dénomination des tables et des clés

TableNames: PascalCase

touches: camelCase

foreignkeys: TableNameInPascalCase_foreignKeyInCamelCase

Exemple: User_pictureId Signification: Cette clé de pictureId provient de la table User.

181
Calvintwr

supprimer le modèle BookArticles et mettre à jour la relation avec:

m.Book.hasMany(m.Article, {through: 'book_articles'});
m.Article.hasMany(m.Books, {through: 'book_articles'});
14
ahiipsa

Voilà comment j'ai résolu le problème similaire j'avais deux modèles un modèle utilisateur

var user = sequelize.define('user', {
    name: {
        Sequelize.STRING(255)
    },
    email: {
        type: Sequelize.STRING(255),
        unique: true,
        validate: {
            isEmail: true
        }
    }
});

et un modèle de rôles

var Role = sequelize.define('role', {
    name: {
        Sequelize.ENUM('ER', 'ALL', 'DL')
    },
    description: {
        type: Sequelize.TEXT
    }
});

J'ai ensuite créé le modèle d'union UserRole

var UserRole = sequelize.define('user_role', {
    id: {
        type: Sequelize.INTEGER,
        primaryKey: true,
        autoIncrement: true
    },
    name: {
        type: Sequelize.ENUM('Admin', 'Staff', 'Customer', 'Owner')
    }
});

Remarque: vous devez définir explicitement l'ID pour UserRole sinon sequelize utilisera les deux clés étrangères dans ce cas user_id et role_id comme clés primaires.

Ensuite, j'ai créé la relation appartient à plusieurs comme suit

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' });
6
Buhiire Keneth

M:M relation à travers la table BookArticles:

m.Book.belongsToMany(m.Article, {through: m.BookArticles});
m.Article.belongsToMany(m.Books, {through: m.BookArticles});
3
Tilekbekov Yrysbek