sequelize で belongTo をするやり方を思い出しやすいようにメモに残します。
準備
mkdir practice-sequelize && cd $_ npm init --yes cat << EOS > .gitignore node_modules npm-debug.log* db EOS mkdir db npm install sqlite sequelize --save npm install sequelize-cli --save-dev git init && git add . && git commit -m 'first commit'
雛形を生成する
$(npm bin)/sequelize init cat << EOS > config/config.json { "development": { "dialect": "sqlite", "storage": "./db/development.db" }, "test": { "dialect": "sqlite", "storage": "./db/test.db" }, "production": { "dialect": "sqlite", "storage": "./db/production.db" } } EOS git add config models && git commit -m 'db initialize'
モデルを作成する
$(npm bin)/sequelize model:create --name Todo --attributes "title:string, complete:boolean" $(npm bin)/sequelize model:create --name User --attributes "email:string" sed -i '' -e 's/\/\/ associations can be defined here/Todo.belongsTo(models.User);/' models/todo.js git add models migrations && git commit -m 'add new models'
マイグレーションを実行
$(npm bin)/sequelize db:migrate
テーブルが作成されている事を確認する
% sqlite3 db/development.db '.schema' CREATE TABLE `SequelizeMeta` (`name` VARCHAR(255) NOT NULL UNIQUE PRIMARY KEY, UNIQUE (name)); CREATE TABLE `Todos` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `title` VARCHAR(255), `complete` TINYINT(1), `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);
Fixture を作る
本来は seeders がそれに相当すると思いますがちょっと使いづらいので無視して自前で作成します。
create test/fixture/{user.js,todo.js,index.js}
mkdir -p test/fixture cat << EOS > test/fixture/user.js 'use strict'; module.exports = (models) => { return models.User.bulkCreate([ { id: 1, email: 'admin@exmaple.com', }, { id: 2, email: 'info@example.com', }, ]) } EOS
cat << EOS > test/fixture/todo.js 'use strict'; module.exports = (models) => { return models.Todo.bulkCreate([ { id: 1, title: 'todo:1', complete: true, UserId: 1 }, { id: 2, title: 'todo:2', complete: true, UserId: 1 }, { id: 3, title: 'todo:3', complete: false, UserId: 2 } ]) } EOS
cat << EOS > test/fixture/index.js 'use strict'; module.exports = (models) => { const Promise = models.Sequelize.Promise; return Promise.all([ require('./user')(models), require('./todo')(models) ]) } EOS
create bin/sync:
cat << EOS > bin/sync #!/usr/bin/env node 'use strict'; const models = require('../models'); const fixture = require('../test/fixture'); models.sequelize.sync({ force: true, logging: console.log, }) .then(() => { return fixture(models); }) .then(() => { return models.sequelize.close(); }) EOS
実行
chmod +x bin/sync bin/sync
使ってみる
mkdir example touch example/todo_list.js
edit example/todo_list.js
cat << EOS > example/todo_list.js 'use strict'; const models = require('../models'); models.Todo.findAll({ include: [models.User] }).then((todos) => { todos.forEach((todo) => { console.log(JSON.stringify(todo)); console.log(JSON.stringify(todo.User)); }); }); EOS
result
:!node example/todo_list.js Executing (default): SELECT `Todo`.`id`, `Todo`.`title`, `Todo`.`complete`, `Todo`.`createdAt`, `Todo`.`updatedAt`, `Todo`.`UserId`, `User`.`id` AS `User.id`, `User`.`email` AS `User.email`, `User`.`createdAt` AS `User.createdAt`, `User`.`updatedAt` AS `User.updatedAt` FROM `Todos` AS `Todo` LEFT OUTER JOIN `Users` AS `User` ON `Todo`.`UserId` = `User`.`id`; {"id":1,"title":"todo:1","complete":true,"createdAt":"2016-03-24T09:22:51.740Z","updatedAt":"2016-03-24T09:22:51.740Z","UserId":1,"User":{"id":1,"email":"admin@exmaple.com","createdAt":"2016-03-24T09:22:51.738Z","updatedAt":"2016-03-24T09:22:51.738Z"}} {"id":1,"email":"admin@exmaple.com","createdAt":"2016-03-24T09:22:51.738Z","updatedAt":"2016-03-24T09:22:51.738Z"} {"id":2,"title":"todo:2","complete":true,"createdAt":"2016-03-24T09:22:51.740Z","updatedAt":"2016-03-24T09:22:51.740Z","UserId":1,"User":{"id":1,"email":"admin@exmaple.com","createdAt":"2016-03-24T09:22:51.738Z","updatedAt":"2016-03-24T09:22:51.738Z"}} {"id":1,"email":"admin@exmaple.com","createdAt":"2016-03-24T09:22:51.738Z","updatedAt":"2016-03-24T09:22:51.738Z"} {"id":3,"title":"todo:3","complete":false,"createdAt":"2016-03-24T09:22:51.740Z","updatedAt":"2016-03-24T09:22:51.740Z","UserId":2,"User":{"id":2,"email":"info@example.com","createdAt":"2016-03-24T09:22:51.738Z","updatedAt":"2016-03-24T09:22:51.738Z"}} {"id":2,"email":"info@example.com","createdAt":"2016-03-24T09:22:51.738Z","updatedAt":"2016-03-24T09:22:51.738Z"}