Jonathan Thurft
Jonathan Thurft

Reputation: 4173

Core data fetching one to many relationship data

I've searched around but I am still unclear about various concepts that I hope someone clarifies for me.

My confusion and headache comes when trying to save into the Exercise / Routine entities while respecting some sort of user's ID.

For my understanding and reading around core data the way I setted core data up, it should work and be able to pull and save information into Routine and Exercise while respecting the user they are working with. Could anyone correct me if i am wrong?

I think I have to do a query that looks something like (in SQL terms)

INSERT INTO Routine (Values) WHERE Routine.userID = user.usersExercise

Is that correct? if that is correct. Now the problem that I've is that I have no idea how to make an inner join of these two entities in coreData code in order to produce a query like that.

Any help is really appreciate it!

enter image description here

Upvotes: 4

Views: 8091

Answers (1)

Dev2rights
Dev2rights

Reputation: 3487

Yes you need to use NSPredicate to get the data related to a specific user. If you are populating a UICollection view then i would recommend also reading up on NSFetchedResultsController.

NSFetchRequest *fetchRequestItems = [[NSFetchRequest alloc] init];
NSEntityDescription *entityItem = [NSEntityDescription entityForName:@"Routine" inManagedObjectContext:self.managedObjectContext];
[fetchRequestItems setEntity:entityItem];

User* myUser = //Code for getting current user out of data store based on some paramator
[fetchRequestItems setPredicate:[NSPredicate predicateWithFormat:@"userID == %@",myUser]];

//Sort by last edit ordered
NSArray *sortDescriptors = [NSArray arrayWithObjects:nil];
[fetchRequestItems setSortDescriptors:sortDescriptors];

NSArray* Routines = [managedObjectContext executeFetchRequest:fetchRequest error:&error];

The thing to note here is you need to set up inverse relationships on your Routine / Exercise objects to compare against the current user in the predicate. Which you have for userID which i presume is an inverse relationship ?

So from the comment i take you havent set the inverse relationship so here is a rough example.

When making a new User on your store you would get somethign like this:

User *thisUser = [NSEntityDescription insertNewObjectForEntityForName:@"User" inManagedObjectContext:self.managedObjectContext];

thisUser.eMail = emailAddress.text;
//And any other paras you might have

Then when making a routine for that user you would do this:

Routine *newRoutine = [NSEntityDescription insertNewObjectForEntityForName:@"Routine" inManagedObjectContext:managedObjectContext];

newRoutine.userId = thisUser;

Then make sure to save the managed object to write the changes to the data store. This then links the 2 objects on the routine side, dont forget to link it on the Users side too for a strict inverse relationship.

To get the user its exactly like i mentioned above:

NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"User" inManagedObjectContext:managedObjectContext];
[fetchRequest setEntity:entity];

NSError* error;
NSArray* Users = [managedObjectContext executeFetchRequest:fetchRequest error:&error];

If you have 1 user then its the first element in the array, if you have many users then use predicates to find the one based on your FB id.

Upvotes: 3

Related Questions