parse.com Cloud Code可防止重复错误

时间:2014-04-06 09:57:45

标签: javascript ios cloud parse-platform

我遵循这里的指示:

https://parse.com/questions/unique-fields--2

var Profile = Parse.Object.extend("Profile");

Parse.Cloud.beforeSave("Profile", function(request, response) {

                       if (!request.object.get("entityID")) {
                            response.error('must have a entity id');
                       } else {

                       var query = new Parse.Query(Profile);
                       query.equalTo("entityID", request.object.get("entityID"));
                       query.first({

                                   success:function(object) {

                                    if (object) {
                                        response.error("already exist");
                                    }
                                    else {
                                        response.success();
                                    }

                                   },
                                   error:function(error) {
                                        response.error("couldnt validate uniqueness for this profile");
                                   }

                        });


                        }
                       });

我有一个配置文件表,唯一键是entityID,插入时,我需要检查具有相同键的条目是否已经存在。

问题是,我无法再更新条目(似乎插入和更新请求都会触发此云代码。

我如何修改它以便

  1. 当我插入时,如果它存在,我忽略它;如果不存在,请插入它。

  2. 我更新时,如果存在,请更新;如果不存在,我会忽略它。

3 个答案:

答案 0 :(得分:4)

我知道这有点旧,但应该提到的是,在Parse实现锁定/等待系统或任意约束强制执行之前,不可能干净地防止带有云代码的重复条目,因为您不能保证只有代码的一个实例在任何给定点运行。即使你有类似的东西:

if entry exists
    update it or don't add it
else
    add it

由于没有锁定,您无法实现自己的约束强制。此外,尝试这样做会使您的API调用加倍,并可能使您陷入更昂贵的计划。即使在最近几个月(仅搜索他们的论坛),Parse工作人员已多次承认这一点,并建议在某些情况下使用原子增量或自动生成的唯一对象ID,但在大多数情况下这是不切实际的。他们还建议运行自动作业以在输入后删除重复项,但这并不能保证在任何给定点上系统中的数据内部一致,即使在作业运行之后也是如此。

最重要的是,如果约束强制执行和整体数据完整性对您的应用程序至关重要,那么Parse还不够成熟,无法满足您的需求。我希望很快能看到这种变化。

答案 1 :(得分:1)

您可以调用自定义云功能来执行您想要的所有操作,而不是使用创建和更新请求。让我有点头疼。

答案 2 :(得分:1)

S.C。是正确的。

与此同时,你可能会变脏并做类似的事情:

Parse.Cloud.afterSave("Profile", function(request) {

    // Find every Profile with same entityID
    var query = new Parse.Query(Profile);
    query.equalTo("entityID", request.object.get("entityID"));

    // Order them by creation in db (oldest in DB first)
    query.ascending("createdAt");

    query.find({

        success:function(results) {

            if (results && results.length > 1) {
                // We have a least one duplicate

                // Destroy every Profile except for the original (the oldest in DB)
                for(var i = (results.length - 1); i > 0 ; i--) {  
                    results[i].destroy();
                    // /!\ In case of concurrent call of afterSave, 
                    // we might run in situation of concurrent deletetion 
                    // of same Profile in this case we might encounter (or not?) some 
                    // time out of this function buuut we will always keep 
                    // the same Profile from being deleted.
                }
            }
            else {
                // No duplicates
            }

        },
        error:function(error) {
        }
     });
 });