How to add multiple class parse objects to a relation? - ios

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

Related

Parse following PFUser

I'm trying to make a follow action with parse on my ios9 project but i have a little problem when retreiving the PFUser from parse using objectId can anyone help me please (the problem is in adding the user ID of current user to the user followed )
- (IBAction)followButtonAction:(id)sender {
PFQuery * query = [PFUser query];
[query whereKey:#"objectId" equalTo:_a.userId];
NSArray *objects = [query findObjects];
PFUser *user= objects.firstObject;
//add the user ID for the cell we are following to the array of followed items in the user class in parse
[[PFUser currentUser] addUniqueObject:_a.userId forKey:#"followed"];
[[PFUser currentUser] saveInBackground];
//add the user ID to the user that the user followed
[user addUniqueObject:[PFUser currentUser].objectId forKey:#"followers"];
[user saveInBackground];
}
Assuming your question is about the long-running operation (as per your comment):
Your query is being executed on the main thread, because you called [query findObjects]. Use findObjectsInBackgroundWithBlock instead, and place all the code after that inside the callback.

Why is a PFRelation saved by saving the PFUser object?

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.

parse web service relational database

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.

How to add PFObjects with different class names to one relation

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 :)

Understanding and using Parse many to many relations

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];

Resources