Similar presentations:
Связь Many -To - Many
1.
фаза 1 · неделя 3 · день 3Many-To-Many
Seeders
2.
План1. Связь Many-To-Many
2. Наполнение БД (Seeders)
3.
Many-To-Many4.
Many-To-ManyДля создания связи Many-To-Many должна использоваться промежуточная
таблица. В примере создана промежуточная таблица Posts_tags, которая
содержит в себе внешние ключи на таблицы Posts и Tags.
5.
МиграцииВ миграции необходимо прописать references для таблиц, которые необходимо связать.
В таблице Posts_tags для атрибутов post_id и tag_id указываем references на
соответствующие таблицы:
post_id: {
tag_id: {
type: Sequelize.INTEGER,
type: Sequelize.INTEGER,
references: {
references: {
model: 'Posts', // tableName
model: 'Tags', // tableName
key: 'id',
key: 'id',
}
}
}
}
6.
Описание моделейДалее нужно прописать associate в моделях. Есть 3 способа описать связь Many-To-Many:
● Связь через промежуточную таблицу
Можно обратиться к Posts и/или Tags и include их между собой
Нельзя обратиться к промежуточной и сделать include
● Две связи один ко многим
Можно обратиться к Posts или Tags и include промежуточную
Можно обратиться к промежуточной и include Posts и/или Tags
Нельзя include Posts и Tags напрямую
● Комбинировать эти два подхода
Можно всё :)
7.
Связь через промежуточную таблицу// Model Post
static associate(models) {
this.belongsToMany(models.Tag, { through: 'Posts_tag', foreignKey:
'post_id' })
}
// Model Tag
static associate(models) {
this.belongsToMany(models.Post, { through: 'Posts_tag', foreignKey:
'tag_id' })
}
В модели Posts_tag ничего не указываем.
8.
Связь через промежуточную таблицуЗапросы, которые доступны:
Post.findAll({ include: Tag })
Tag.findAll({ include: Post })
Запросы, которые не доступны:
Posts_tag.findAll({ include: Tag })
Posts_tag.findAll({ include: Post })
9.
Две связи один ко многим// Model Post
static associate(models) {
this.hasMany(models.Posts_tag, { foreignKey: 'post_id' })
}
// Model Tag
static associate(models) {
this.hasMany(models.Posts_tag, { foreignKey: 'tag_id' })
}
// Model Posts_tag
static associate(models) {
this.belongsTo(models.Post, { foreignKey: 'post_id' })
this.belongsTo(models.Tag, { foreignKey: 'tag_id' })
}
10.
Две связи один ко многимЗапросы, которые доступны:
Posts_tag.findAll({ include: Post })
Posts_tag.findAll({ include: Tag })
Post.findAll({ include: Posts_tag })
Tag.findAll({ include: Posts_tag })
Запросы, которые не доступны:
Post.findAll({ include: Tag })
Tag.findAll({ include: Post })
11.
Комбинированный вариант// Model Post
// Model Tag
static associate(models) {
static associate(models) {
this.belongsToMany(models.Tag, {
this.belongsToMany(models.Post, {
through: 'Posts_tag',
through: 'Posts_tag',
foreignKey: 'post_id',
foreignKey: 'tag_id',
});
});
this.hasMany(models.Posts_tag, {
this.hasMany(models.Posts_tag, {
foreignKey: 'post_id',
foreignKey: 'tag_id',
as: 'post',
as: 'tag',
});
}
});
}
12.
Комбинированный вариантВ модели Posts_tag указываем belongsTo как в предыдущем примере.
Если модель ссылается на одну и туже таблицу, как в предыдущем примере,
то необходимо использовать alias (as) в ассоциациях и методах sequelize.
Основное назначение алиасов - устранение неоднозначности при наличии
одноименных таблиц/полей.
13.
Комбинированный вариантПримеры запроса с “as”:
Post.findAll({ include: { as: 'post', model: Posts_tag } });
Tag.findAll({ include: { as: 'tag', model: Posts_tag } });
14.
Вложенные includeЕсть возможность совершать вложенные include.
На примере из предыдущего слайда можно сделать вложенные include:
Post.findAll({
include: {
as: 'post',
model: Posts_tag,
include: Tag
}
})
15.
Seeders16.
СидыСиды - это действие наполнения БД тестовыми данными.
В случае, если откатить миграции и снова накатить, то все данные будут
потеряны. Благодаря сидам можно в один клик снова наполнить БД и
заниматься разработкой, а не наполнением БД в очередной раз.
17.
СидыЧтобы создать сид, нужно воспользоваться командой sequelize-cli:
npx sequelize-cli seed:generate --name tag
После этой команды, в вашей папке seeders появится новый файл. Он будет
похож на файл миграции. В нем также будут функции up и down.
18.
Сидыasync up(queryInterface, Sequelize) {
async down(queryInterface, Sequelize) {
await queryInterface.bulkInsert(
'Tags',
null, {});
[
}
{ name: 'JavaScript' },
{ name: 'React' },
],
{},
);
}
await queryInterface.bulkDelete('Tags',
19.
СидыДля того, чтобы накатить сиды нужно воспользоваться командой:
npx sequelize-cli db:seed:all
Для того, чтобы откатить сиды нужно воспользоваться командой:
npx sequelize-cli db:seed:undo:all
Важно!
Порядок сидов также важен, как и в случае с миграциями. Сперва сидим
независимые данные (без внешних ключей), после зависимые.
20.
СидыЕсли несколько раз запустить команду сида, то сиды каждый раз будут дублировать
данные.
Чтобы этого избежать, можно задать сидам такое же поведение, как и у миграций
(будет проверка, был ли засижен файл). Это делается с помощью добавления в
database.json в свойство development следующих строк:
"seederStorage": "sequelize",
"seederStorageTableName": "SequelizeData"