Sign up for a Parse account to implement this tutorial and more!

Sign Up

Icon_one_to_many
One-to-Many Relationships

In this tutorial, you'll learn how to create a one-to-many relationship between two PFObjects in a simple blogging application.

iOS
PFObject
Relationships
Screencast

Download code for this tutorial:

.zip File GitHub

If your application is storing more than one class of objects, it's likely that these classes will need to be related to one another. For example, in a blogging application, each user would be associated with several posts. This is called a one-to-many relationship. Creating this type of relationship between a Post and PFUser object allows you to later retrieve the Posts associated with any given PFUser. This short tutorial will show how easy it is to create this kind of relationship using Parse.

We will look at a simple blogging application, where users can view a list of their blog posts and add new ones. This application contains two view controllers. The NewPostViewController has a text view where the user will be able to compose and save new Post objects, and the BlogTableViewController includes a table view, which we will populate with the user’s blog posts.

Creating the Relationship

Let's begin by adding the necessary code to create and save a Post in the NewPostViewController. This view controller already has a navigation bar button on the right-hand side, which is linked to the addButtonTouchHandler: method. This is where we’ll add our implementation. We'll start by creating a new PFObject with the class Post, and then setting its "textContent" key to the text entered by the user. Next, we'll create a relationship between our Post and the user who's currently logged in. To do this, we'll add an "author" key to the Post object and set the value to the current user. Parse makes this very easy by allowing us to directly set the value of a key to a PFUser object.

Here’s what this code might look like:

- (void)addButtonTouchHandler:(id)sender
{
    // Create Post
    PFObject *newPost = [PFObject objectWithClassName:@"Post"]; 

    // Set text content
    [newPost setObject:[textView text] forKey:@"textContent"];  

    // Create relationship
    [newPost setObject:[PFUser currentUser] forKey:@"author"];  

    // Save the new post
    [newPost saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
        if (!error) {
           // Dismiss the NewPostViewController and show the BlogTableViewController
           [self dismissModalViewControllerAnimated:YES];
        }
    }];
}

In order to get the the PFUser that is currently logged in, notice that we used the static method [PFUser currentUser]. In this sample application the app delegate takes care of automatically creating and logging in a user for you. However, feel free to modify this code and experiment.

Querying the Relational Data

Now that we can create blog posts, we move our attention to the BlogTableViewController. Here, we will add the necessary code to display the user’s posts in the table view. A left navigation bar button is already created and linked to the refreshButtonTouchHandler: method, which will be used for our implementation. In order to display the user’s posts in the table view, we can make a query to Parse.

We'll begin by creating a PFQuery object using the Post class. To get the Post objects composed by a particular PFUser, we will need to use the relationship we just created. Recall that we've defined each Post object as being associated with a single PFUser through the "author" key. We can then configure the query to return all Post objects, where the "author" key is equal to the current PFUser. This code should look like this:

- (void)refreshButtonHandler:(id)sender {
     // Create a query
     PFQuery *postQuery = [PFQuery queryWithClassName:@"Post"];    

     // Follow relationship
     [postQuery whereKey:@"author" equalTo:[PFUser currentUser]];  

     [postQuery findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
         if (!error) {
             postArray = objects;           // Store results
             [self.tableView reloadData];   // Reload table
       }
     }];
}

Displaying Posts in the TableView

Notice that in the refreshButtonHandler: method, we stored the query results in the view controller's postArray property. We can then use this property in the tableView:cellForRowAtIndexPath: method to display the posts. This is as simple as adding the following code to this method:

PFObject *post = [postArray objectAtIndex:indexPath.row];
[cell.textLabel setText:[post objectForKey:@"textContent"]];

The application should now be able to create Post objects, set a one-to-many relationship between Posts and PFUsers, as well as use a query to obtain all Posts associated with a given user. One-to-many relationships can be created between any two PFObjects using the same techniques you've learned here.