pre('save')
ミドルウェア内で、プロパティの新しい/着信値をそのプロパティの以前の値 (現在データベースに保存されているもの) と比較したいと思います。
Mongoose はこれを行うための機能を提供していますか?
Mongoose では、比較を行うカスタム セッターを構成できます。pre('save') だけでは、必要なものは得られませんが、一緒に:
schema.path('name').set(function (newVal) {
var originalVal = this.name;
if (someThing) {
this._customState = true;
}
});
schema.pre('save', function (next) {
if (this._customState) {
...
}
next();
})
複数のフィールドのいずれかの変更を検出するソリューションを探していました。完全なスキーマのセッターを作成できないように見えるため、仮想プロパティを使用しました。私はいくつかの場所でレコードを更新しているだけなので、これはそのような状況ではかなり効率的な解決策です:
Person.virtual('previousDoc').get(function() {
return this._previousDoc;
}).set(function(value) {
this._previousDoc = value;
});
Person が移動し、住所を更新する必要があるとします。
const person = await Person.findOne({firstName: "John", lastName: "Doe"});
person.previousDoc = person.toObject(); // create a deep copy of the previous doc
person.address = "123 Stack Road";
person.city = "Overflow";
person.state = "CA";
person.save();
次に、pre フックで、次のような _previousDoc のプロパティを参照するだけで済みます。
// fallback to empty object in case you don't always want to check the previous state
const previous = this._previousDoc || {};
if (this.address !== previous.address) {
// do something
}
// you could also assign custom properties to _previousDoc that are not in your schema to allow further customization
if (previous.userAddressChange) {
} else if (previous.adminAddressChange) {
}
正直なところ、ここに掲載されている解決策を試してみましたが、古い値を配列に格納し、値を保存して、違いを確認する関数を作成する必要がありました。
// Stores all of the old values of the instance into oldValues
const oldValues = {};
for (let key of Object.keys(input)) {
if (self[key] != undefined) {
oldValues[key] = self[key].toString();
}
// Saves the input values to the instance
self[key] = input[key];
}
yield self.save();
for (let key of Object.keys(newValues)) {
if (oldValues[key] != newValues[key]) {
// Do what you need to do
}
}