3

How would you check if a relationship has been established when adding data to core data? Currently I have a TO MANY relationship between two of my entities.

I am attempting to create a detail view but am struggling and i'm not sure if its due to a relationship not being established or if my issue is with passing the data over to the new view controller.

enter image description here

I am adding the the data to the core data entities using the following code. Does this look right when establishing a relationship between the two?

ExcerciseInfo *info = [_fetchedResultsController objectAtIndexPath:indexPath];
NSManagedObject *routineEntity = [NSEntityDescription insertNewObjectForEntityForName:@"Routines"inManagedObjectContext:context];
NSManagedObject *routineEntityDetail = [NSEntityDescription insertNewObjectForEntityForName:@"RoutinesDetails" inManagedObjectContext:context];
    
[[routineEntityDetail valueForKey:@"name"] addObject:routineEntity];
    
[routineEntity setValue: info.name  forKey:@"routinename"];
[routineEntityDetail setValue: info.details.muscle  forKey:@"image"];
   
NSError *error = nil;

Error Investigation:

I used one of the suggested methods but am still getting this fault when i tested the relationship in a NSLog(@"ExTitle *** %@",Ex.routinedet); with routinedet being the @property (nonatomic, retain) NSSet *routinedet; in the core data generated NSObject relationship model:

Relationship 'routinedet' fault on managed object (0x749ea50) <Routines: 0x749ea50> (entity: Routines; id: 0x749c630 <x-coredata://C075DDEC-169D-46EC-A4B7-972A04FCED70/Routines/p1> ; data: {
    routinedet = "<relationship fault: 0x8184a20 'routinedet'>";
    routinename = "Leg Crunch";

I have also tested to make sure the segue is working and its is as;

self.title = Ex.routinename;
RoutinesDetails *info;
NSLog(@"Image *** %@",info.image);

which shows the title as the correct name but returns image string as null.

pkamb
  • 33,281
  • 23
  • 160
  • 191
Sgillon
  • 147
  • 12

2 Answers2

3

Assuming that the entities are defined as in Core Data Detail View with relationship, the following code establishes a relationship between the two objects:

[routineEntityDetail setValue:routineEntity forKey:@"routineinfo"];

It sets the relationship pointer from routineEntityDetail to routineEntity.

Since routinedet is the inverse relationship to routineinfo, routineEntityDetail is automatically added to the routinedet relationship of routineEntity.

This does not make sense:

[[routineEntityDetail valueForKey:@"name"] addObject:routineEntity];

And this looks OK:

[routineEntity setValue: info.name  forKey:@"routinename"];
[routineEntityDetail setValue: info.details.muscle  forKey:@"image"];
Community
  • 1
  • 1
Martin R
  • 529,903
  • 94
  • 1,240
  • 1,382
  • Thanks again martin. So currently it wouldn't work? Is `[[routineEntityDetail valueForKey:@"name"] addObject:routineEntity];` not needed? – Sgillon Jul 09 '13 at 20:31
  • @user2221799: `name` is an attribute of `RoutineDetails`, not a relationship. – Martin R Jul 09 '13 at 20:33
  • so on that basis i would simple change it to `rountineinfo` to match the relationship. Thanks – Sgillon Jul 09 '13 at 20:47
  • @user2221799: Yes, but `routineinfo` is a to-one relationship and `addObject` does not make sense here. The first code in my answer shows how to set the relationship. – Martin R Jul 09 '13 at 20:50
  • brillant. you have been very helpful today martin – Sgillon Jul 09 '13 at 20:52
  • I actually just tested it out and got an error as viewable in the main question – Sgillon Jul 09 '13 at 21:57
  • @user2221799: A "fault" is not an error!! Core Data will retrieve the values from the store file when needed. – Martin R Jul 09 '13 at 22:21
  • @user2221799: There is nothing to "forgive". YOU decide when and which answer you accept! – Martin R Jul 09 '13 at 22:26
1

Without seeing your datamodel I can't be sure, but I believe you would want something like this:

ExcerciseInfo *info = [_fetchedResultsController objectAtIndexPath:indexPath];
Routine  *routine = [NSEntityDescription insertNewObjectForEntityForName:@"Routine"inManagedObjectContext:context];
RoutineDetail  *routineDetail = [NSEntityDescription insertNewObjectForEntityForName:@"RoutineDetail" inManagedObjectContext:context];

routine.routineName = info.name;
routineDetail.image = info.details.muscle;

[routine addRoutineDetailsObject:routineDetail];

That assumes that a routine has many routineDetails, and that the relationship is named as it would be by generating the NSManagedObject subclass in XCode. I also removed the plural name in the class names, as model classes are generally singular.

If my assumptions are off I apologize.

The datamodel I was coding for is here: enter image description here

KHansenSF
  • 604
  • 4
  • 7
  • 1
    data model can be seen at the start of this post [link]http://stackoverflow.com/questions/17553654/core-data-detail-view-with-relationship . Is that what you expected? – Sgillon Jul 09 '13 at 20:45
  • Yours doesn't follow the naming conventions that I am accustomed to, but that's not a bug deal. I feel the bigger issue is the generation of the NSManagedObject subclasses. In XCode you'll find that tool on the edit menu when you are looking at your datamodel. – KHansenSF Jul 09 '13 at 21:18
  • But you don't reference the subclass in your code. I meant generation of the .h and .m interface and implementation files, named for your entities. But if you have it working and are happy with it, then we're done here. :-) – KHansenSF Jul 09 '13 at 22:23