前回は、MVC に沿って、コントローラーを作成しました。

views/index.ejs

<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title><%= pageTitle %></title>
  </head>
  <body>
    <main>
      <h1>メニュー</h1>
      <p>メニュー一覧</p>
      <% if(menus.length > 0) { for (let menu of menus){ %>
      <p><%= menu.menuTitle %></p>
      <%} %> <% } else { %>
      <p>注文がありません</p>
      <% } %>
    </main>
  </body>
</html>

views/menu.ejs

<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <link rel="stylesheet" href="/css/styles.css" />
    <title><%= pageTitle %></title>
  </head>
  <body>
    <main>
      <form action="/menu" method="POST">
        <input type="text" name="title" />
        <button type="submit">メニューを追加する</button>
      </form>
    </main>
  </body>
</html>

index.js

const express = require("express");
const app = express();
const path = require("path");

app.set("view engine", "ejs");
app.set("views", "views");

const menuRoutes = require("./routes/index.js");
const menus = require("./routes/menu.js");

app.use(express.urlencoded({ extended: true }));

app.use(express.static(path.join(__dirname, "public")));

app.use("/", menus);
app.use(menuRoutes);

app.use((req, res, next) => {
  res.status(404).send("<h1>ページが見つかりません</h1>");
});

app.listen(8000, () => console.log("Server is running ..."));

routes/index.js

const express = require("express");
const router = express.Router();

const menuController = require("../controllers/menus");

router.get("/", menuController.getAddMenus);

module.exports = router;

routes/menu.js

const express = require("express");
const router = express.Router();

const menuController = require("../controllers/menus");

router.get("/menu", menuController.getAddMenu);

router.post("/menu", menuController.postAddMenu);

module.exports = router;

controllers/menus.js

const Menu = require("../models/menu");

exports.getAddMenu = (req, res, next) => {
  res.render("menu", { pageTitle: "メニュー追加" });
};

exports.postAddMenu = (req, res, next) => {
  const menu = new Menu(req.body.title);
  menu.save();
  res.redirect("/");
};

exports.getAddMenus = (req, res, next) => {
  const menus = Menu.fetchAll();
  res.render("index", {
    pageTitle: "メニュー一覧",
    menus,
  });
};

今回は、MVC の『M』である、モデルを作成します。

今現在、コントローラーがモデルの役割を担っているので、コントローラーから分離させます。

まず、models フォルダを作成し、その中に menu.js を作成します。

データを格納するために、空の配列を作成します。

const menus = [];

Menu クラスを作成し、その中でデータを管理します。

Menu クラスは、エクスポートしてコントローラーで使えるようにします。

module.exports = class Menu {

};

メニューを定義するために、constructor 関数を使います。

module.exports = class Menu {
  constructor(title) {
    this.menuTitle = title;
  }

};

save メソッドを使用し、menus にデータを格納するようにします。

module.exports = class Menu {
  constructor(title) {
    this.menuTitle = title;
  }

  save() {
    menus.push(this);
  }

};

データを取り出せるように、fetchAll メソッドを作成します。

データを取り出せるように、fetchAll を静的メソッドにしておきましょう。

module.exports = class Menu {
  constructor(title) {
    this.menuTitle = title;
  }

  save() {
    menus.push(this);
  }

  static fetchAll() {
    return menus;
  }
};

モデルが完成したので、コントローラーからモデルを使用できるようにします。

controllers フォルダの menus.js を開きます。

require を使って、モデルを呼び出します。

const Menu = require("../models/menu");

const menus = [];は、モデルにあるので削除します。

postAddMenumenus.push({ menuTitle: req.body.title });を削除します。

フォームから送信されたデータを Menu クラスに格納するようにします。

exports.postAddMenu = (req, res, next) => {
  const menu = new Menu(req.body.title);
  menu.save();
  res.redirect("/");
};

これで、データを Menu クラスに格納することができました。

最後に、getAddMenusで、menusを取り出すようにします。

そのためには、Menu クラスで作成した、fetchAllを使います。

exports.getAddMenus = (req, res, next) => {
  const menus = Menu.fetchAll();
  res.render("index", {
    pageTitle: "メニュー一覧",
    menus,
  });
};

完成しましたので、ブラウザで確認すると、

image2

image3

image4

無事、データのやりとりができました。

ブログ一覧