Подтвердить что ты не робот

Как реализовать много-много ассоциаций в sequelize

У меня есть две таблицы: книги и статьи со многими отношениями между ними. Таблица соединения - это BookArticles.

модели/books.js

module.exports = function(sequelize, DataTypes) {
  return Food = sequelize.define("Book", {
    id: {
      type: DataTypes.INTEGER,
      primaryKey: true,
      allowNull: false,
      autoIncrement: true,
      unique: true
    }
  });
}

модели/articles.js

module.exports = function(sequelize, DataTypes) {
  return Food = sequelize.define("Article", {
    id: {
      type: DataTypes.INTEGER,
      primaryKey: true,
      allowNull: false,
      autoIncrement: true,
      unique: true
    }
  });
}

модели/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
    },
  });
}

И модели /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});

но я не мог получить статьи в книгах

Как я могу получить его?

4b9b3361

Ответ 1

удалить модель BookArticles и связать обновление с:

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

Ответ 2

Update 17 Feb 15: 1. Новый v2 использует 2x .belongsToMany() для N: M.

Было много проблем в понимании всех этих ассоциаций.

В общем, я думаю, мы смущены тем, что создаются таблицы, и какие методы получают ассоциации.

Ниже текст - это то, что я написал, чтобы стандартизировать, как я хочу, чтобы моя команда обрабатывала все это. Что касается соглашений об именах, вы можете игнорировать его, если вы просто разрешите Sequelize по умолчанию.

Однако рекомендуется указывать ваши соглашения по многим причинам.

Коротко:

O: O, настройте a Parent.hasOne(Child) AND Child.belongsTo(Parent).

O: M, настройте Parent.hasMany(Child) И Child.belongsTo(Parent).

N: M *, настройте Parent.belongsToMany(Child, {through: 'Parent_Child', foreignKey: 'Parent_rowId'}) и Child.belongsToMany(Parent, {through: 'Parent_Child', foreignKey: 'Child_rowId'}).

Методы, полученные hasOne(), hasMany() и принадлежатTo()/принадлежатToMany()

Чтобы понять, почему мы делаем вышеуказанные ассоциации, мы начинаем, зная, какие методы мы получаем для каждой модели.

hasOne():

При установке Parent.hasOne(Child), доступных для parent экземпляра DAO:

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

hasMany():

При настройке Parent.hasMany(Child) доступны методы parent экземпляра DAO:

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

belongsTo()/belongsToMany:

При настройке Child.belongsTo(Parent) доступны методы child экземпляра DAO:

child.getParent,
child.setParent,
child.createParent

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

Синтаксис для установления отношений. И наши соглашения

Для O: O и O: M:

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

Обратите внимание, что мы явно определили, что наши foreignKeys являются Parent_childID. Это связано с тем, что мы хотим, чтобы это соглашение PascalCase_camelCase для TableName_keyName.

Отношение Many to Many

Для отношения N: M сделайте следующее:

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: Использование "сквозной" теперь является обязательным. В качестве стандарта, используя параметр "сквозной", мы явно определяем все crosstable имена для согласованности и меньше gotchas.

Вышеизложенное создаст Parent_Child с параметрами RelationshipId и Relationship2ID.

Sequelize может автоматически создавать foreignKeys, но я обычно определяю свой собственный.

Соглашения об именах таблиц и ключей

Имена таблиц: PascalCase

: camelCase

foreignkeys: TableNameInPascalCase_foreignKeyInCamelCase

Пример: User_pictureId Значение: Этот ключ pictureId был получен из таблицы User.

Ответ 3

Вот как я решил аналогичную проблему, у меня были две модели пользовательской модели

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

и модель ролей

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

Затем я создал модель объединения UserRole

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

Примечание: вы должны явно определить идентификатор для UserRole, иначе secelize будет использовать два внешних ключа в этом случае user_id и role_id в качестве ваших основных ключей.

Тогда я создал принадлежность ко многим отношениям следующим образом

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

Ответ 4

M:M отношение через таблицу BookArticles:

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