in my project I have a user relation for the key userPosts. I want to add to this relation different objects with different class names, in this example a category from a UIPicker, something like this:
PFObject *post = [PFObject objectWithClassName:selectedCategory];
//do stuff with the object...
[object save];
PFRelation *relation = [PFUser currentUser] relationForKey:#"userPosts"];
[relation addObject:post];
[PFUser currentUser] saveInBackground];
The problem is that when I'm trying to execute this code it throws me a runtime error saying basically that I can only add objects to a relation with one class name. How do I override/fix it? Thanks :)
Related
I want to create a PFQuery for a PFRelation to find objects where the specified relation has zero objects in it. Here's what I've tried:
PFQuery *categoryQuery = [CatalogCategory query];
[categoryQuery whereKeyDoesNotExist:#"subcategories"];
But I get an error saying I can't use this operator on a PFRelation key. How else could I achieve what I'm looking for?
Have you tried [categoryQuery whereKey:#"subcategories" equalTo:nil]?
It may be that the whereKeyDoesNotExist: method is unavailable for objects of the PFRelation type.
so I am having trouble understanding how a PFRelation saves, I have this code:
PFUser *user = [PFUser currentUser];
PFRelation *relation = [user relationForKey:#"likes"];
[relation addObject:post];
[user saveInBackground];
Why is it that updating the user i.e. [user saveInBackground] updates the PFRelation field "likes" for that user? Does this use a single API call or does [relation addObject: post]; also require an API call?
Any help would be greatly appreciated.
Thanks
In your case 1 API request is used under circumstances.
Take a look at PFObject [straight from Parse.com]:
// Create the post
PFObject *myPost = [PFObject objectWithClassName:#"Post"];
myPost[#"title"] = #"I'm Hungry";
myPost[#"content"] = #"Where should we go for lunch?";
// Create the comment
PFObject *myComment = [PFObject objectWithClassName:#"Comment"];
myComment[#"content"] = #"Let's do Sushirrito.";
// Add a relation between the Post and Comment
myComment[#"parent"] = myPost;
Here you are setting attributes or properties to the PFObject but nothing ever happens until you save it, you can do anything to the object like change it, update it, doesn't matter, but backend wise, it won't update unless you tell it to which is where save comes in play :
[myComment saveInBackground];
In short, you can add relations, pointers and numerous parameters all day long, but nothing happens until you tell it to happen : [saveInBackground];
Because you made it a direct correlation to user it saves it to that user because you told it to. Because you specified a relation to the user, once you save the user properties the relation will also be saved. However, this doesn't create more API requests.
I am using parse to develop an iOS app.
For the database, I have three tables, named user, UserAndCourse, and course.
Where UserAndCar stores a pointer to user and course.
the tables looks like:
My problem is:
How can I query the courses that belongs to the current user on iOS. i.e that look into UserAndCourse to find the rows that user column is current user and query for the course object that is pointed to by the course column.
Can I do this in a single relational query? or I have to query the UserAndCourse table rows first and then query the course it pointed to.
I suggest to use PFRelation, that way you don't need to create new table for relations like userAndCourse. Parse automatically will link through the relation. You just need to create relation between them and do what you want.
Saving relation;
PFUser *user = [PFUser currentUser];
PFRelation *relation = [user relationForKey:#"course"];
[relation addObject:coursePFObject];
[user saveInBackground];
And query when you need to reach them;
PFRelation *relation = [user relationForKey:#"course"];
PFQuery *query = [relation query];
[query findObjectsInBackgroundWithBlock:^(NSArray *results, NSError *error) {
// results contains all the people who subscribe to course
}];
Moreover you can specify your course by adding more queries on it;
PFQuery *query = [relation query];
[query whereKey:#"name" equalTo:#"Math"];
[query findObjectsInBackgroundWithBlock:^(NSArray *results, NSError *error) {
// results contains all the people who subscribe Math course
}];
I think it's better way to shape your tables in parse. Otherwise you need to create table for each relation.
Hope it helps also if you need more detail this can be helpful.
in my project I have a user relation for the key userPosts. I want to add to this relation different objects with different class names, something like this:
PFObject *post = [PFObject objectWithClassName:selectedCategory];
// doing stuff with the object
[object save];
PFRelation *relation = [PFUser currentUser] relationForKey:#"userPosts"];
[relation addObject:post];
[PFUser currentUser] saveInBackground];
The problem is that when I'm trying to execute this code it throws me a runtime error saying basically that I can only add objects to a relation with one class name.
How do I override/fix it? Thanks
I have 2 tables in Parse like so:
Users:
(PFUsers table with all Parse data)
belongsToGroups (A Parse Relation to Groups which is many to many)
Groups:
groupId
name
groupMembers (A Parse Relation to Users which is also many to many)
I have the following code:
PFObject *groups = [PFObject objectWithClassName:#"Groups"];
groups[#"name"] = name;
syncUsers[#"isActive"] = [NSNumber numberWithInt:1];
//[groups saveInBackground];
PFUser *current = [PFUser currentUser];
PFRelation *relation = [syncUsers relationforKey:#"groupMembers"];
[relation addObject:current];
[groups saveEventually];
PFRelation *relation2 = [current relationforKey:#"belongsToGroups"];
[relation2 addObject:groups];
[current saveEventually];
First, the top 2 blocks of code work fine, but how do I update the relationship in Users so that I can do View Relation in Parse and see my groups?
Two, do I need to create the Relation in users AND groups so that it can be many to many?
You can use whereKey:equalTo: on a relation column and pass it a PFObject. This query will then return all Teacher objects which have this student in their "students" relation:
PFQuery *query = [PFQuery queryWithClassName:#"Teacher"];
[query whereKey:#"students" equalTo:student];
In this example, the student is a PFObject with a className that matches the relation in "students". If this is a relation of PFUsers and you're looking for the current user's "Teacher"s, you'd use:
PFQuery *query = [PFQuery queryWithClassName:#"Teacher"];
[query whereKey:#"students" equalTo:[PFUser currentUser]];
First for a relation you need that both objects exist in the Parse Database. Then you must use the PFRelation object and save the object with the relation.
I recommend using CodeCloud for stablishing relationships so you can share the code with Android or Web Apps.
// Objects
PFObject *student = [PFObject objectWithoutDataWithClassName:#"Student" objectId:#"xauj37H"];
PFObject *teacher = [PFObject objectWithoutDataWithClassName:#"Teacher" objectId:#"xJdcj238"];
// Add a student to the teacher object
// Get the students relation
PFRelation *studentsForTeacher = [teacher relationForKey:#"students"];
// Add a student
[studentsForTeacher addObject:student];
// save the teacher, use InBackground instead
[teacher save];
// Now add a teacher for the student
PFRelation *teachersForStudent = [student relationForKey:#"teachers"];
[teachersForStudent addObject:teacher];
// Save the student
[student save];
// And now you can query the students of a teacher or the teachers of a student
// Students for a Teacher
PFQuery *studentsQuery = [studentsForTeacher query];
[studentsQuery find];
// Teachers for a Student
PFQuery *teachersQuery = [teachersForStudent query];
[teachersQuery find];