over 4 years ago

下面這些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 回傳碼

← 老闆與工程師:溝通的重要性 在Swift下用內建SDK產生UUID的兩種方式 →
 
comments powered by Disqus