Kalzem
Kalzem

Reputation: 7492

Save 2 different PFObjects eventually or fail both

Using Parse SDK for iOS, I have 2 tables :

Game
- UserA : Pointer <_User>
- UserB : Pointer <_User>
- Round : Number
- IsTurnOfUserA : Bool

RoundScore
- GameId : Pointer <Game>
- User   : Pointer <_User>
- Score  : Number
- etc

A game is done in 3 rounds between 2 users.

When a user ends a round, it toggles Game.IsTurnOfUserA and saves the score for the round to RoundScore table.

In iOS, I didn't find a way to update Game table AND save a RoundScore eventually (maybe later if there is no network).

Both must be done or none at all, but I don't want to end up with only one of the 2 query to be successful and the other one failed.

With Cloud Code, it should be easy to do so but there is no call eventually function.

Update: Maybe there is something to try with Parse's local database ? But I don't know that tool yet.

Important: RoundScore has a field that depends on Game. If Game Object is new, it doesn't have an ObjectId yet, but I still need to link it to the RoundScore Object.

Upvotes: 0

Views: 107

Answers (2)

Kalzem
Kalzem

Reputation: 7492

As Timothy Walters suggested, here is the hack without any background job:

I created a fake table that has the columns of both tables Game and RoundScore

GameAndRoundScore
- Game_UserA
- Game_UserB
- RoundScore_GameId
- RoundScore_Score
- etc

In Cloud Code, I added this function before save

Parse.Cloud.beforeSave("GameAndScoreRound", function(request, response) {
    var Game = Parse.Object.extend("Game");
    var game = new Game();
    game.set("UserA", request.object.get("game_UserA"));
    game.set("UserB", request.object.get("game_UserB"));
    game.save.then(function(newGame) {
        var RoundScore = Parse.Object.extend("RoundScore");
        var roundScore = new RoundScore();
        //roundScore.set(...)
        return scoreRound.save();
    }).then(function(newRoundScore) {
        response.success();
    });
});

Then for the fake table data, I can either leave it as it is or set a background job that empties it or even empty the table manually on the Parse Backend.

Upvotes: 0

Timothy Walters
Timothy Walters

Reputation: 16874

Unfortunately it isn't possible with saveEventually.

What you would need to do is implement your own network checking code and call a cloud method that will save both. That would be the best option.

A hack you could try as an alternative is to save the combined data to another class and have a background job on the server turn that single temporary row into a row in each table, then remove the temporary row.

The drawbacks of this hack is that the background job can run every 15 minutes only, so there might be up-to 15 minutes delay. It also adds extra complexity and overhead to your app.

Upvotes: 1

Related Questions