それでは中編で棚上げしていたsyncメソッドを提供するAPIの実装を書いていこう。
Sequelizeのサンプルを見てもわかるように、syncメソッドはimportメソッドによってインスタンス化されたモデルオブジェクトに対する呼び出し(Project.sync)と、Sequelizeオブジェクトに対する呼び出し(sequelize.sync)の2パターンある。モデルオブジェクトに対してsync()を実行すると、対応するテーブル定義だけが構築される。 Sequelizeオブジェクトに対してsync()を実行すると、データベース全体が構築される。また、sync()の引数に{ force: true }を渡すと、既存のテーブルを一旦削除(DROP)してゼロからテーブルを作り直す(再構築)。
APIとしては、個々のテーブル(モデルオブジェクト)に対する呼び出しと、全体(Sequelizeオブジェクト)に対する呼び出しを分けて提供する。それぞれのメソッド名を/devel/sync/:table、/devel/syncとして、routes/index.jsに以下のコードを追加しよう。
module.exports = function(app, config) {
var sequelize = require('dbconn')(config)
, models = require('models')(sequelize);
// Database migration
app.configure('development', function() {
var sync = require('./sync');
app.post('/devel/sync/:table', sync.one(models));
app.post('/devel/sync', sync.all(sequelize));
});
app.resource('users', require('./users'), { id: 'id' });
};
syncメソッドを使うのはあくまで開発過程だけであって、リリースしたときにAPIを叩かれてしまってはたまらないので、development環境でだけ動作するようにしておく。また、ブラウザからうっかりAPIを叩くことがないように、HTTPメソッドもPOSTのみ受け付けるようにしておく。
続いてroutes/sync.jsにsyncモジュールを実装していく。
var done = function(res) {
return function() {
res.send('Done.\n');
};
},
dberr = function(res) {
return function(e) {
res.statusCode = 500;
res.send(e);
};
};
module.exports =
{
all: function(sequelize) {
return function(req, res) {
sequelize.sync(req.body).success(done(res)).error(dberr(res));
};
},
one: function(models) {
return function(req, res) {
var model = models[req.params.table];
if(model != undefined) {
model.sync(req.body).success(done(res)).error(dberr(res));
}
else {
res.send(404);
}
};
}
};
繰り返すが、開発過程で使うものなので、正常時、エラー時の出力は自分がわかるレベルでよい。
さぁ、これで準備が整った。中編でmodels/users.jsで実装したUserモデル定義を思い出してほしい。モデル定義をしただけでデータベース上にはまだテーブル定義がない状態である。
まずはnodeを起ち上げておく。
$ NODE_PATH=libs node app.js
別ターミナルを開いて、いま実装したsyncモジュールのAPIを実行してみよう。
$ curl -X POST localhost:3000/devel/sync Done.
nodeを起ち上げたターミナルには、テーブルが構築された際に実行されたSQL文がダンプされているはずだ。
$ NODE_PATH=libs node app.js Sequelize connecting to test on localhost as h2plus Express server listening on port 3000 in development mode Executing: CREATE TABLE IF NOT EXISTS `users` ( `userame` VARCHAR(255), `password` char(40), `id` INTEGER NOT NULL auto_increment , `createdAt` DATETIME NOT NULL, `updatedAt` DATETIME NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB;
models/users.jsでは、id、createdAt、updatedAtというカラムを定義していないが、これはSequelizeが(勝手に)生成しているものである。
mysqlshowコマンドを実行して、実際にテーブルができていることを確認してみるといいだろう。
$ mysqlshow -u h2plus -p test users
usersテーブルだけ構築するならば、
$ curl -X POST localhost:3000/devel/sync/users
を実行すればいい。
Userモデルの定義を途中で変更して、テーブルを再構築したい場合は、
$ curl -X POST -d 'force=1' localhost:3000/devel/sync/users
を実行すれば、sequelize.sync({ force: true })が実行されるようになる。
あとは、アプリケーションのモデル定義をmodels配下に追加していき、routes/index.jsにロジックを実装していくだけである。
2 コメント