下面這些schema code在mongoose v3.8
下運作正常
var OrderSchema = new Schema({
orderId: { type: String, required: true },
createdDate: { type: Date, required: true },
...
paymentType: {
type: String,
subType: String
},
paymentResult: {
...
},
_user: { type: Schema.Types.ObjectId, ref: 'User', required: true}
});
但我把mongoose升級到v4.0.5
版的時候,儲存資料時出現驗證錯誤(Validation Error)
var newOrder = new DB.Order({
orderId: orderId,
createdDate: new Date().getTime(),
paymentType: {
type: 'CREDIT',
subType: 'INSTANT'
},
paymentResult: {
......
},
_user: user._id
});
newOrder.save(function(err) { console.log(err); });
err
的錯誤內容是
{ [ValidationError: Order validation failed]
message: 'Order validation failed',
name: 'ValidationError',
errors:
{ paymentType:
{ [CastError: Cast to String failed for value "[object Object]" at path "paymentType"]
message: 'Cast to String failed for value "[object Object]" at path "paymentType"',
name: 'CastError',
kind: 'String',
value: [Object],
path: 'paymentType' } } }
我觀察了一下其他沒問題的code
發現如果我把定義paymentType
的方式從
createdDate: { type: Date, required: true },
....
paymentType: {
type: String,
subType: String
},
改成
createdDate: { type: Date, required: true },
....
paymentType: {
type: { type: String } ,
subType: { type: String }
},
就都正常了
看起來「SomeField : SomeType」在subdocs上的定義,在版本4已經不能使用了
不過官網的範例還是這樣寫
而且從Mongoose 版本3到4的升級指南(migration guide)沒有提到這一點
所以我就到GitHub上的Mongoose開了一個Issue了
Update
GitHub的Issue已經有人回覆了 看來是我耍笨了,因為paymentType的type: String 他就誤以為整個paymentType是String型別了 所以我用Object寫進去當然後出現Validation錯誤,真的是好笨啊... 可是為何v3沒事呢
沒事不要亂 npm update 啊,你可以看出來這是信用卡收款的資料
要是客戶沒有寄信來抱怨,我就不知道到底發生了什麼事,還好他沒有當我是詐騙
如果你真的要在production mode上做npm update
建議在package.json
裡面,千萬不要像我直接在裡面使用*
號,不管怎樣都會更新到最新版。
{
"name": "MyApp",
"version": "1.0.2",
"private": true,
"scripts": {
"start": "node ./bin/www"
},
"dependencies": {
"body-parser": "^1.8.4",
"mongoose": "*"
...
}
}
建議改成
"~4.0.5"
代表 4.0.x (Bug修正等等更新,舉例:會更新4.0.6, 4.1.2就不會)
"^4.0.5"
則相當於會更新到4.x.x (新版,有新功能,但會相容,舉例:會更新4.1.0, 5.0.1就不會)
"4.0.5"
永遠只會用4.0.5這版本(但是有Bug你npm update就更新不到了)
這裏我用了
"*"
則會永遠是最新的版本
才造成此次的烏龍,我應該使用^
才對
照理說你用npm install mongoose --save
時,預設他都會給你用^
才對
我不知道是哪次自己亂改改到的
不管如何,給大家參考看看囉
看看這筆延遲了三個小時、PayPal重試通知我的Server 10次才拿到可愛的HTTP 200 回傳碼