node.js+React CMS開発-モデル定義
CMS開発シリーズの続きです
- node.js+ReactベースのCMS開発をはじめます
- node.js+React CMS を設計する(外部仕様))
- node.js+React CMS を設計する(データベース仕様))
- node.js+React CMS開発-サーバー雛形を作成
今回は前回作成した雛形にmongooseスキーマ&モデルの定義を実装します。
目次
- 目次
- mongooseのインストール
- auto increment を行うmongoose-sequenceを導入
- ユーザーパスワードの暗号化のためmongoose-bycryptを導入
- モデル定義をするディレクトリ構造を決める
- 共通module
- モデル定義
- まとめ
mongooseのインストール
$ cd ~/nexpress $ npm install --save mongoose
auto increment を行うmongoose-sequenceを導入
MySQLなどのRDBで使われる自動採番(sequence) を利用したいのでmongoose-sequenceをインストール
$ npm install --save mongoose-sequence
ユーザーパスワードの暗号化のためmongoose-bycryptを導入
パスワードを暗号化して保存するためフィールドの暗号化と照合ができるプラグインmongoose-bycryptをインストール
$ npm install --save mongoose-bycrypt
モデル定義をするディレクトリ構造を決める
nexpress ├── README.md ├── app.js ├── bin ├── config.js <----- アプリケーション共通の設定情報 ├── db.js <----- mongodb接続や,mongoose,puluginに関する共通設定 ├── models/ <----- ここにモデルごとにファイルで配置する ├── node_modules/ ├── package-lock.json ├── package.json ├── public/ <----- 静的ファイル ├── routes/ <----- ルーティング └── views/ <----- ビュー
共通module
config.js
アプリケーション全体を通して使用するパラメータなどを定義します。
// config.js const config = { app: { port: 3000 }, db: { host: 'localhost', port: 27017, name: 'nexpress' }, secret: { key: '#%$SomethingRandomString&%$' } }; module.exports = config;
db.js
- データベースへの接続
- mongoose プラグインの追加
var config = require('./config'); var mongoose = require('mongoose'); // mongoose 利用 const AutoIncrement = require('mongoose-sequence')(mongoose); // 自動採番プラグイン const { db: { host, port, name } } = config; const option = { useMongoClient: true, poolSize: 10 }; mongoose.Promise = global.Promise; mongoose.connect(`mongodb:\/\/${host}:${port}/${name}`, option); // 接続 mongoose.AutoIncrement = AutoIncrement; module.exports = mongoose;
モデル定義
node.js+React CMS を設計する(データベース仕様))で定義したスキーマをnexpress/models
ディレクトリに定義する
user.js
ユーザー情報
var mongoose = require('../db'); // 接続とsequenceの初期化が行われている var Schema = mongoose.Schema; // 定義 var userSchema = new Schema ({ user_id : Number, login : String, password : String }); // user_idは自動採番 userSchema.plugin(mongoose.AutoIncrement, { inc_field: 'user_id'}); // passwordフィールドを自動暗号化 userSchema.plugin(require('mongoose-bcrypt'),{ fields: ['password'] }); module.exports = mongoose.model('User', userSchema);
site.js
サイト情報
var mongoose = require('../db'); var Schema = mongoose.Schema; var siteSchema = new Schema ({ site_id: Number, name : String, title : String }); siteSchema.plugin(mongoose.AutoIncrement, { inc_field: 'site_id' }); module.exports = mongoose.model('Site', siteSchema);
user-site.js
サイトの所有者、利用者、共同編集者ユーザーの登録情報。 ユーザーとサイトのリレーション
var mongoose = require('../db'); var Schema = mongoose.Schema var userSiteSchema = new Schema ({ user_id : { type: Number, refs: 'User' }, site_id : { type: Number, refs: 'Site' }, role : String }); module.exports = mongoose.model('UserSite', userSiteSchema);
category.js
カテゴリ情報
var mongoose = require('../db'); var Schema = mongoose.Schema; var categorySchema = new Schema ({ site_id: { type: Number, refs: Site }, category_id: Number name : String, title : String }); categorySchema.plugin(mongoose.AutoIncrement, { inc_field: 'category_id'}); module.exports = mongoose.model('Category', categorySchema);
category-category.js
カテゴリ同士の親子関係 カテゴリ間リレーション定義
var mongoose = require('../db'); var Schema = mongoose.Schema var contentCategorySchema = new Schema ({ category_id : { type: Number, refs: 'Category' }, content_id : { type: Number, refs: 'Content' } }); module.exports = mongoose.model('ContentCategory', contentCategorySchema);
content.js
コンテンツ、記事情報
var mongoose = require('../db'); var Schema = mongoose.Schema; var contentSchema = new Schema ({ site_id: { type: Number, refs: Site }, content_id: Number, user_id: { type: Number, refs: User}, title : String, summary : String, image: String, publish_date: { type: Date, default: Date.now }, expire_date: { type: Date, default: null }, article: [Schema.Types.Mixed] }); contentSchema.plugin(mongoose.AutoIncrement, { inc_field: 'content_id'}); module.exports = mongoose.model('Content', contentSchema);
content-category.js
コンテンツとカテゴリのリレーション
var mongoose = require('../db'); var Schema = mongoose.Schema var contentCategorySchema = new Schema ({ category_id : { type: Number, refs: 'Category' }, content_id : { type: Number, refs: 'Content' } }); module.exports = mongoose.model('ContentCategory', contentCategorySchema);
tag.js
タグ情報
var mongoose = require('../db'); var Schema = mongoose.Schema; var tagSchema = new Schema ({ site_id : { type: Number, refs: Site }, tag_id : Number, name : String }); tagSchema.plugin(mongoose.AutoIncrement, { inc_field: 'tag_id'}); module.exports = mongoose.model('Tag', tagSchema);
content-tag.js
var mongoose = require('../db'); var Schema = mongoose.Schema var contentTagSchema = new Schema ({ tag_id : { type: Number, refs: 'Tag' }, content_id : { type: Number, refs: 'Content' } }); module.exports = mongoose.model('ContenTag', contentTagSchema);
file.js
添付画像やアップロードされたファイルの情報
var mongoose = require('../db'); var Schema = mongoose.Schema; var fileSchema = new Schema ({ site_id: { type: Number, refs: Site }, file_id: Number, user_id: { type: Number, refs: User}, path : String }); fileSchema.plugin(mongoose.AutoIncrement, { inc_field: 'file_id' }); module.exports = mongoose.model('file', fileSchema);
まとめ
- アプリケーション全体で共有する設定情報を config.js に定義
- データベース接続およびmongoose共通環境を db.js に定義
- モデル
models/*.js
にモデルごとに定義 - 各モデルはコントローラで使用するモデルの必要な分だけrequireする
- データベース接続はpoolして使いまわす
- アプリケーションでは自動採番フィールド(
*_id
)をキーにしてリレーションする - user.passwordは暗号化する
- Index,Validationは別途行う
これで基本的なモデルの定義ができました。
: ├── models │ ├── category-category.js │ ├── category.js │ ├── content-category.js │ ├── content-tag.js │ ├── content.js │ ├── file.js │ ├── site.js │ ├── tag.js │ ├── user-site.js │ └── user.js :
つづく