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
おしまい