Reputation: 4764
IOS newb from mysql background working on an app that ties into a web server backend. If I have two entities or objects enjoying many to many relationships such as item and tag, in MYSQL I would have three tables, the table of items, the table of tags and a third table of tag-item relationships.
Table 1 Tags ID|tag
Table 2 Items ID|item
Table 3 Tagitems ID|tagid|itemid
If I want to do this in core data would it be appropriate to also have three entities?
Entity 1: Tags id|tagname
Entity 2: Items id|itemname
Entity 3: Tagitems id|tagid|itemid
Seems straightforward enough but just want to make sure I am understanding core data correctly.
Upvotes: 1
Views: 141
Reputation: 21536
If your intermediate table has no other attributes, then you do not need to model it yourself. Just create a to-many relationship from Entity 1
to Entity 2
, and a to-many relationship from Entity 2
to Entity 1
, and make each relationship the inverse of the other. CoreData will build and manage the intermediate table for you (and its existence is largely hidden from you). The model editor should look something like this:
When you generate subclasses, CoreData will create NSSet properties for the relationships:
Tag.h
#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h>
@class Item;
@interface Tag : NSManagedObject
@property (nonatomic, retain) NSString * tagName;
@property (nonatomic, retain) NSSet *items;
@end
@interface Tag (CoreDataGeneratedAccessors)
- (void)addItemsObject:(Item *)value;
- (void)removeItemsObject:(Item *)value;
- (void)addItems:(NSSet *)values;
- (void)removeItems:(NSSet *)values;
@end
Item.h
#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h>
@class Tag;
@interface Item : NSManagedObject
@property (nonatomic, retain) NSString * itemName;
@property (nonatomic, retain) NSSet *tags;
@end
@interface Item (CoreDataGeneratedAccessors)
- (void)addTagsObject:(Tag *)value;
- (void)removeTagsObject:(Tag *)value;
- (void)addTags:(NSSet *)values;
- (void)removeTags:(NSSet *)values;
@end
You can then use the core data generated accessors to add and remove relationships - note that you set the relationships directly between objects, you don't have to use IDs; CoreData is handling the IDs for you "in the shadows". So you could do something like this:
Tag *actionTag = [NSEntityDescription insertNewObjectForEntityForName:@"Tag" inManagedObjectContext:self.context];
actionTag.name = @"Action";
Tag *dramaTag = [NSEntityDescription insertNewObjectForEntityForName:@"Tag" inManagedObjectContext:self.context];
dramaTag.name = @"Drama";
Item *movie = [NSEntityDescription insertNewObjectForEntityForName:@"Item" inManagedObjectContext:self.context];
movie.name = @"Pride and Prejudice";
[movie addTagsObject:dramaTag];
If your intermediate table does have other attributes, then you should implement Entity 3
, and add whatever attributes you need (but do not implement the 'id' keys - leave that to CoreData). The relationships from Entity 1
to Entity 3
should be to-many, but its inverse should be to-one; likewise from Entity 2
to Entity 3
should be to-many, and its inverse to-one:
Entity 2 <---->> Entity 3 <<----> Entity 1
Upvotes: 1