1

CloudCode beforeSave関数を使用して、新しいオブジェクトのオブジェクトと比較しようとしています。更新で送信されたフィールドを既存の値と比較する必要があります。問題は、オブジェクトを正しく取得できないことです。クエリを実行すると、常に送信されたオブジェクトから値が取得されます。

更新: 別のアプローチを試してみたところ、古いレジスタ (既に解析に保存されているもの) を取得できました。しかし、リクエストで送信された新しいものは、古いものによって上書きされました。何?!もう 1 つの問題は、コードが を送信したresponse.success()にもかかわらず、更新が保存されなかったことです。 ここでかなり明白な何かが欠けていると思います。または、バグか何かに直面しています...

新しいアプローチ

Parse.Cloud.beforeSave('Tasks', function(request, response) {
  if ( !request.object.isNew() )
  {
    var Task = Parse.Object.extend("Tasks");
    var newTask = request.object;
    var oldTask = new Task();
    oldTask.set("objectId", request.object.id);
    oldTask.fetch()
        .then( function( oldTask )
    {
        console.log(">>>>>> Old Task: " + oldTask.get("name") + " version: " + oldTask.get("version"));
        console.log("<<<<<< New Task: " + newTask.get("name") + " version: " + newTask.get("version"));
        response.success();
    }, function( error ) {
            response.error( error.message );
        }
    );
    }
});

オブジェクトが送信されました {"name":"LLL", "version":333}

ログ

 I2015-10-02T22:04:07.778Z]v175 before_save triggered for Tasks for user tAQf1nCWuz:
 Input: {"original":{"createdAt":"2015-10-02T17:47:34.143Z","name":"GGG","objectId":"VlJdk34b2A","updatedAt":"2015-10-02T21:57:37.765Z","version":111},"update":{"name":"LLL","version":333}}
 Result: Update changed to {}
 I2015-10-02T22:04:07.969Z]>>>>>> Old Task: GGG version: 111
 I2015-10-02T22:04:07.970Z]<<<<<< New Task: GGG version: 111

注: cURL と解析コンソールでログインをテストしています。

CloudCode beforeSave

Parse.Cloud.beforeSave("Tasks", function( request, response) {
  var query = new Parse.Query("Tasks");
  query.get(request.object.id)
    .then(function (oldObj) {
        console.log("-------- OLD Task: " + oldObj.get("name") + " v: " + oldObj.get("version"));
        console.log("-------- NEW Task: " + request.object.get("name") + " v: " + request.object.get("version"));
    }).then(function () {
        response.success();
    }, function ( error) {
        response.error(error.message);
    }
  );
});

cURL リクエスト

curl -X PUT \
-H "Content-Type: application/json" \
-H "X-Parse-Application-Id: xxxxx" \
-H "X-Parse-REST-API-Key: xxxxx" \
-H "X-Parse-Session-Token: xxxx" \
-d "{\"name\":\"NEW_VALUE\", \"version\":9999}" \
https://api.parse.com/1/classes/Tasks/VlJdk34b2A

JSON レスポンス

"updatedAt": "2015-10-02T19:45:47.104Z"

LOG ログにはの値と新しい値が出力されますが、アクセス方法もわかりません。

I2015-10-02T19:57:08.603Z]v160 before_save triggered for Tasks for user tAQf1nCWuz:
Input: {"original":{"createdAt":"2015-10-02T17:47:34.143Z","name":"OLD_VALUE","objectId":"VlJdk34b2A","updatedAt":"2015-10-02T19:45:47.104Z","version":0},"update":{"name":"NEW_VALUE","version":9999}}
Result: Update changed to {"name":"NEW_VALUE","version":9999}
I2015-10-02T19:57:08.901Z]-------- OLD Task: NEW_VALUE v: 9999
I2015-10-02T19:57:08.902Z]-------- NEW Task: NEW_VALUE v: 9999
4

5 に答える 5

0

クエリを実行するのではなく、変更されたが保存されていないキーを確認することで、変更された属性を確認できます。

JS SDK にはdirtyKeys()、変更されたキーを返す が含まれています。これを試してみてください。

var attributes = request.object.attributes; 
var changedAttributes = new Array(); 

for(var attribute in attributes) {

    if(object.dirty(attribute)) { 
        changedAttributes.push(attribute);
        // object.get(attribute) is changed and the key is pushed to the array
    }
}

明確にするために、元の属性の値を取得するには、呼び出しget()て保存前の値をロードする必要があります。これは別の API リクエストとしてカウントされることに注意してください。

于 2015-10-02T20:31:08.033 に答える
0

2021年頃にこのスレッドに来ている人は、保存する前にクライアントSDKにサーバーデータをロードしている場合は、関数のcontextオプションでクライアントSDKからそのサーバーデータを渡してから使用することで、この問題を解決できますクラウド機能save()で。beforeSave afterSave

// eg JS client sdk
const options  = { 
  context: {
    before: doc._getServerData() // object data, as loaded
  } 
}
doc.save(null, options)
// #beforeSave cloud fn
Parse.Cloud.beforeSave(className, async (request) => {
  const { before } = request.context
  // ... do something with before ... 
})

_getServerData()警告:クライアントの関数に属性がロードされていない場合、これは役に立ちません。

2 番目の警告: parse は、クラウド関数でシリアル化 (非) を処理しません。たとえば、次のようになります。

{
  before: { // < posted as context
    status: {
      is: 'atRisk',
      comment: 'Its all good now!',
      at: '2021-04-09T15:39:04.907Z', // string
      by: [Object] // pojo
    }
  },
  after: {
    status: { // < posted as doc's save data
      is: 'atRisk',
      comment: 'Its all good now!',
      at: 2021-04-09T15:39:04.907Z, // instanceOf Date
      by: [ParseUser] // instanceOf ParseUser
    }
  }
}
于 2021-04-14T19:09:06.780 に答える
0

私があなたなら、古い値をパラメーターとしてクラウド関数に渡し、request.params.(パラメーターの名前) でアクセスできるようにします。古い値を取得する別の方法があるとは思いません。古い SO の質問では、.get() を使用できると言われていましたが、それが機能していないと主張しています。実際にバージョンにすでに 9999 が含まれていない限り...

編集 - beforeSave は通常の関数のように呼び出されないと思います...現在のタスクと更新しようとしているバージョンを渡す「バージョンの更新」関数を作成してください。

于 2015-10-02T20:31:19.353 に答える