sequelize tutorial(2) many to many
sequelize tutorial many to many
sequelize で many to many をするやり方を思い出しやすいようにメモに残します。
準備
http://okamuuu.hatenablog.com/entry/2016/03/25/163856
モデルを作成する
Role を準備します
$(npm bin)/sequelize model:create --name Role --attributes "name:string"
sed -i '' -e 's/\/\/ associations can be defined here/Todo.belongsToMany(models.User, {through: 'UserRole'});/' models/role.js
git add models migrations && git commit -m 'add new models'
それから User を編集します。
User.belongsToMany(models.Role, {through: 'UserRole'});
マイグレーションを実行
$(npm bin)/sequelize db:migrate
テーブルが作成されている事を確認します。UserRole は後の作業で作成されます。
% sqlite3 db/development.db '.schema' CREATE TABLE `SequelizeMeta` (`name` VARCHAR(255) NOT NULL UNIQUE PRIMARY KEY, UNIQUE (name)); CREATE TABLE `Roles` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `name` VARCHAR(255), `createdAt` DATETIME NOT NULL, `updatedAt` DATETIME NOT NULL); CREATE TABLE `Users` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `email` VARCHAR(255), `createdAt` DATETIME NOT NULL, `updatedAt` DATETIME NOT NULL); CREATE TABLE `Todos` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `title` VARCHAR(255), `complete` TINYINT(1), `createdAt` DATETIME NOT NULL, `updatedAt` DATETIME NOT NULL, `UserId` INTEGER REFERENCES `Users` (`id`) ON DELETE SET NULL ON UPDATE CASCADE);
Fixture を作る
create test/fixture/role.js
cat << EOS > test/fixture/role.js
'use strict';
module.exports = (models) => {
return models.Role.bulkCreate([
{
id: 1,
name: "admin"
},
{
id: 2,
name: "operator"
}
])
}
EOS
cat << EOS > test/fixture/index.js
'use strict';
module.exports = (models) => {
const Promise = models.Sequelize.Promise;
return Promise.all([
require('./role')(models), // role を追加
require('./user')(models),
require('./todo')(models)
])
}
EOS
bin/sync を実行する
bin/sync
create example/user_role.js
cat << EOS > example/user_role.js
'use strict';
const co = require('co');
const models = require('../models');
co(function*() {
console.log('=== before ===');
let users = yield models.User.findAll({include: [models.Role]});
users[0].Roles.forEach((role) => {
console.log('user[0] ', role.name);
});
users[1].Roles.forEach((role) => {
console.log('user[1] ', role.name);
});
const roles = yield models.Role.findAll();
yield users[0].addRole(roles);
yield users[1].addRole(roles[0]);
console.log('=== after ===');
users = yield models.User.findAll({include: [models.Role]});
users[0].Roles.forEach((role) => {
console.log('user[0] ', role.name);
});
users[1].Roles.forEach((role) => {
console.log('user[1] ', role.name);
});
}).catch(console.log);
EOS
実行する前に結果が見やすくなるように config/config.json で logging を false に設定します。
{
"development": {
"dialect": "sqlite",
- "storage": "./db/development.db"
- },
+ "storage": "./db/development.db",
+ "logging": false
+ },
"test": {
"dialect": "sqlite",
"storage": "./db/test.db"
- },
+ },
"production": {
"dialect": "sqlite",
"storage": "./db/production.db"
実行
:!node example/user_role.js === before === === after === user[0] admin user[0] operator user[1] admin
おしまい