ullstrm
ullstrm

Reputation: 10170

parse.com: How to compare pointer-keys with objects?

I am using the backend service parse.com for a iOS app and I have a problem with querying it properly. I need help with the method whereKey:matchesKey:inQuery;

I have this code:

//NOT WORKING
PFQuery *query1 = [PFQuery queryWithClassName:@"Object"];

PFQuery *query2 = [PFQuery queryWithClassName:@"ObjectsRelations"];
[query2 whereKey:@"user" equalTo:[PFUser currentUser]];

[query1 whereKey:@"objectId" matchesKey:@"objectPointer" inQuery:query2];
[query1 findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
    // No objects
}];

It is not working the way I want. I have tried several ways for it to compare the key "objectPointer" in class "ObjectsRelations" (which is a pointer to an instance of class Object) to the actual Object in query 1. I do not get any objects back, because the comparison does not work as I want, since the key objectId is just a string and the key objectPointer is a pointer to a Object.

When I run this code, I get the intended result, but this requires me to do two api-requests to get the actual objectId as a string!

//WORKING
PFQuery *query = [PFQuery queryWithClassName:@"Object"];

PFQuery *query2 = [PFQuery queryWithClassName:@"ObjectRelations"];
[query2 whereKey:@"user" equalTo:[PFUser currentUser]];

[query2 findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
    PFObject *firstObject = [((PFObject*)[objects firstObject]) objectForKey:@"objectPointer"];

[query whereKey:@"objectId" equalTo:firstObject.objectId];

[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
    //Getting the objects correctly from the class Object!
}];
}];

How to do this with a single api-request? How to compare a instance of a Class to a pointer of a class with a query?

Something like this is what i want to do: (Pseudo Code)

[query1 where:SELF matches:@"objectPointer" inQuery:query2];

Any suggestions?

Upvotes: 4

Views: 5996

Answers (3)

Johann Chang
Johann Chang

Reputation: 1391

Instead of adding an additional column with type String to contain the objectID it points to, I would suggest to add a column on each object with type Pointer to point to the object itself. This would dramatically reduce the amount of the columns you have to add. The only downside is this must be done on Cloud Code.

At this question's scenario, you'll have two queries like:

//Inner query
//Library containing pointer<Deck> & pointer<User>
PFQuery * subscriptions = [PFQuery queryWithClassName:@"subscription"];
[subscriptions whereKey:@"User" equalTo:[PFUser currentUser]];
//Outer query
//Pull down a list of deckStore objects not included in the subscriptions for current user
PFQuery * decks = [PFQuery queryWithClassName:@"deckStore"];

Then instead of:

[decks whereKey:@"objectId" doesNotMatchKey:@"deckString" inQuery:subscriptions];

You can do this:

[decks whereKey:@"this" doesNotMatchKey:@"deck" inQuery:subscriptions];

Here's a sample of what the Cloud Code should be added:

Parse.Cloud.afterSave("Deck", function(request) {
    var deck = request.object;

    // To make sure this is the first time of "afterSave" of this object.
    if (deck.createdAt.getTime() == deck.updatedAt.getTime()) {
        // "this" is the column which contains the pointer of the object itself.
        if (deck.get("this") == null) {
            deck.set("this", deck);
            deck.save();
        }
    }
}

Upvotes: 1

MCS
MCS

Reputation: 11

I have the same problem. This is my solution:

PFQuery *query1 = [PFQuery queryWithClassName:@"tableClass"];
[query1 whereKey:@"objectId" equalTo:[(PFObject *)[object objectForKey:@"pointerField"] objectId]];

PFObject *obj1 = [query1 getObjectWithId:[(PFObject *)[object objectForKey:@"pointerField"] objectId]];
NSString *pointerName = [obj1 objectForKey:@"name"];

Upvotes: 0

OdieO
OdieO

Reputation: 7002

I just searched this exact same problem and there are a number of questions on the Parse forum regarding it:

Trouble with nested query using object_id
Assistance with relational query
Compare string to pointer in query with does not match key in query

The first one explains a hack to include an extra field (in this case) in your ObjectRelations class. This key/field would be a string that would be the objectId of the pointer. It would be in addition to the key/field that holds the pointer.

If you look through the questions you can see that as of now there doesn't seem to be an answer directly from Parse regarding this.

Upvotes: 2

Related Questions