はかせだけど博士じゃない

無職が就活しないでプログラミングとかする

N予備校のプログラミング入門メモ17

はじめに

妹とデートしてきた。

4章 実践サーバーサイドプログラミング

18.予定の一覧の表示

講座用のプロジェクトをcloneしてnpm startしたところ、DBのエラーが出た。

Unhandled rejection SequelizeDatabaseError: column "scheduleId" does not exist
    at Query.formatError (/home/vagrant/workspace/schedule-arranger-4018/node_modules/sequelize/lib/dialects/postgres/query.js:357:14)
    at Query.<anonymous> (/home/vagrant/workspace/schedule-arranger-4018/node_modules/sequelize/lib/dialects/postgres/query.js:88:19)
    at emitOne (events.js:96:13)
    at Query.emit (events.js:188:7)
    at Query.handleError (/home/vagrant/workspace/schedule-arranger-4018/node_modules/pg/lib/query.js:108:8)
    at Connection.<anonymous> (/home/vagrant/workspace/schedule-arranger-4018/node_modules/pg/lib/client.js:171:26)
    at emitOne (events.js:96:13)
    at Connection.emit (events.js:188:7)
    at Socket.<anonymous> (/home/vagrant/workspace/schedule-arranger-4018/node_modules/pg/lib/connection.js:109:12)
    at emitOne (events.js:96:13)
    at Socket.emit (events.js:188:7)
    at readableAddChunk (_stream_readable.js:176:18)
    at Socket.Readable.push (_stream_readable.js:134:10)
    at TCP.onread (net.js:547:20)

まだ何もいじっていないがscheduleIdが存在しないという旨のエラーのようなので一応コードを確認するも特に問題がない。ということでDBの方が不整合になっているのかと思ってpsqldrop databaseしてcreate databaseしたところ、今度はちゃんと起動した。前回の写経で変な風にtypoしたくせにつじつまが合って起動できてしまったといったところか。

index.jadeにログイン/ログアウトボタンを追加してRouterオブジェクトのindex.jsでテンプレートにユーザ情報のオブジェクトを渡すように修正。

新規予定作成画面のテンプレート、そこからPOSTを受け取るRouterオブジェクトを実装する。認証を確認するハンドラ関数も実装しておき、Routerのget関数などの第二引数にしていすることで呼び出し時に認証が確認されるようにできる。

'use strict';

function ensure(req, res, next) {
  if (req.isAuthenticated()) { return next(); }
  res.redirect('/login');
}

module.exports = ensure;
const authenticationEnsurer = require('./authentication-ensurer');

router.get('/new', authenticationEnsurer, (req, res, next) => {
  res.render('new', { user: req.user });
});

上記のようにするとログインしていない状態で予定作成画面/newにアクセスするとログイン画面にリダイレクトされる。

予定作成に使うUUIDを実装する。

yarn add node-uuid@1.4.7

インストールしたらv4という関数を呼び出すとUUID文字列を取得できる。

予定と候補を保存する機能を実装する。sequelizeオブジェクトのbulkCreate関数で複数のデータをDBに保存できる。

Promiseについて。そういえば解説されてなかった。非同期でよく見るやつ、というイメージだったけど解説もだいたいそんな感じだった(失礼)。

index.jadeに自分で作った予定の一覧を表示するように修正。each inを使ってテーブルの行をループで表示する。Routerオブジェクトからテンプレートに予定の一覧を渡すのを忘れずにやる。以前もやったfindAll関数を使って自分が作った予定一覧を取得する。

/schedule/:scheduleIdを実装する。:scheduleIdはUUIDの文字列。

RouterオブジェクトのfindOne関数は1行を取得する。

ここでincludeというのが急に出てきた。(忘れてるだけかもしれない)

  Schedule.findOne({
    include: [
      {
        model: User,
        attributes: ['userId', 'username']
      }],

事前に Schedule.belongsTo(User, {foreignKey: 'createdBy'});と従属の設定をしているのでこうやってユーザー情報が取得できる、というもののようだ。たぶん。userプロパティにユーザー情報が設定される。

練習問題で予定が表示されることのテストを書いたが、そこでexpect関数でテストしたあとにend関数内でテストで作成したデータを削除する処理が書かれている。

  it('予定が作成でき、表示される', (done) => {
    User.upsert({ userId: 0, username: 'testuser' }).then(() => {
      request(app)
        .post('/schedules')
        .send({ scheduleName: 'テスト予定1', memo: 'テストメモ1\r\nテストメモ2', candidates: 'テスト候補1\r\nテスト候補2\r\nテスト候補3' })
        .expect('Location', /schedules/)
        .expect(302)
        .end((err, res) => {
          let createdSchedulePath = res.headers.location;
          request(app)
            .get(createdSchedulePath)
            .expect(/テスト予定1/)
            .expect(/テストメモ1/)
            .expect(/テストメモ2/)
            .expect(/テスト候補1/)
            .expect(/テスト候補2/)
            .expect(/テスト候補3/)
            .expect(200)
            .end((err, res) => {
              // テストで作成したデータを削除
              let scheduleId = createdSchedulePath.split('/schedules/')[1];
              Candidate.findAll({
                where: { scheduleId: scheduleId }
              }).then((candidates) => {
                candidates.forEach((c) => { c.destroy(); });
                Schedule.findById(scheduleId).then((s) => { s.destroy(); });
              });
              if (err) return done(err);
              done();
            });
        });
    });
  });

19.出欠の表示と更新

2次元のデータ構造についての話。特別新しい話はなかった気がする。ApplicationオブジェクトにRouterオブジェクトを設定する際、同じパスに対して複数のRouterオブジェクトを設定しているのはこういうのもあるのかという感じ。

20.コメントの表示と更新

出欠の更新、コメントの更新APIを実装して、jQueryとwebpackを入れてAJAXでそれぞれが更新できるようにした。

一時中断してたけど日をまたいだので一旦投稿。