0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Node.js,Expressメモ⑤の5

Posted at

ここのところ寒いですね。GWも明日からは雨が続くようです。こんにちは。

今回はPart5のサブページ5番目です。
https://developer.mozilla.org/en-US/docs/Learn/Server-side/Express_Nodejs/Displaying_data/Book_list_page

こっからは同じようなものがつづくようなのでまとめてやってしまうかも?です。

bookページのリスト表示

完成品はコチラ
image.png

ここでは本のリストと著者のリストを表示させればよさそうです。

mongoDBのBooksをみると著者は当然別のテーブルのidが書かれています。
image.png

なのでbooksのリストの各要素のauthor.idをauthorテーブルから置き換えればOKですね。

bookControllerのbook_list

前回と同じように関数を作ってpugファイルを作成します。

exports.book_list = function(req, res, next){
    Book.find({}, "title author").populate("author").exec(function(err, list_books){
        if(err){return next(err);}
        res.render("book_list", {title: "Book List", book_list: list_books});
    });
};

ここでまたちょっとわからないところがあります。
findは検索だと思いますが第一引数はフィルターだったかと思います。
第二引数の"title author"とは?

ちょっとmongooseのModel.find()をみてみます
https://mongoosejs.com/docs/api.html#model_Model.find

Model.find(conditions<object>, projection<object|string>, options<object>, callback<function>)
だそうです。
・conditions
{}にフィルタをいれるようです。{name: "john"}など
・projection
 そうか、selectっぽいですね。sqlでいうところのSELECT title, athour FROM booksってことですね!
・option
 条件みたいです。
・callback
 ここはfunctionを入れるようですが、まだピンときません。。

populate

うーん。。これはまたわからない!

とりあえずドキュメントを張ります。
https://mongoosejs.com/docs/populate.html

説明によると他のコレクションを参照できる代替手段になると。
例をみるとモデルのスキーマに設定されているようなのでbookのmodelをみてみます。

author: {type: Schema.Types.ObjectId, ref: "Author", required: true}

ここのrefというのがそれっぽいです。
設定するのは文字列なのでここと一致させているということだと思います。

models/author.js
//一番最後のマッピング部分
module.exports = mongoose.model("Author", AuthorSchema);
var AuthorSchema = new Schema(
    {
	first_name: {type: String, required: true, max: 100},
	family_name: {type: String, required: true, max: 100},
	date_of_birth: {type: Date, default: Date.now},
	date_of_death: {type: Date, default: Date.now},
    }
);

authorの定義がこれなので、books.author.first_nameとかも可能なのかな?と思います。

execの中のfunctionこれもよくわからない。。

res.render

何はともあれfunctionの第2引数のlist_booksにbookのモデルとそれに付随したauthorのモデルが入っているとします。
はいっているのでしょう。

だとしたらbook_list.pugで使えるアトリビュートは
book.title
book.summary
book.isbn
book.genre
book.url < 関数
book.author.first_name
book.author.family_name
book.author.date_of_birth
book.author.date_of_death
になります。

genreもリファレンスされていますがこれはどういう扱いでしょう。2つとも欲しい場合は?
一応2つ繋げて書くこともできるようです。
Book.find({}, "title author").populate("author").populate("genre").exec(function(err, list_books))

pugにbook.genreといれたらオブジェクトが表示されました。
が、欲しい感じでは受け取れていません。authorと比べてgenreは配列だから?という気もしますが
そちらはおいおい見ていけたらと思います。

book_list.pug

さて今度はこれをレンダリングするためのpugファイルを作成します。

extends layout

block content
  h1= title

  ul
    each book in book_list
      li
        a(href=book.url) #{book.title} 
        | (#{book.author.name})
        

    else
      li There are no books.

上部は定型文でlayoutを継承してblockのcontentを置き換えますよという記述。
今回はfor 分が入っています。each文っていうんですかね。

#{}は#{アトリビュート(virtual関数?)}という用途もあるようです。

さてPart5はこの後12まで続きますが大体ここまで書いたことの繰り返しなので
割愛します!
だんだんページができてくるのは嬉しいものです。

つづく

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?