views:

41

answers:

2

alt text

Above is my data model diagram. Everytime i create a Car whcih contains a model and make, it adds a car object to core data. The problem is that it also adds 1 make and 1 model to the core data, so i get duplicates.

for example, in the following code, it saves 1 car object 2 models, and 2 makes, so I get a duplicate Make in my table (2 "Nissan"). How can i avoid this? is it possible to create primary keys?

In the following example i want to assume that make and models already exists, and a car is only referencing to them, so how can I avoid inserting into make, and model, and only insert into car?

- (void)MyCode
{
     [self AddCar:@"Nissan" @"Rogue"];
     [self AddCar:@"Nissan" @"Murano"];
}


- (void)AddCar :(NSString*)_make :(NSString*)_model
{
    Car *car = [[Car alloc] initWithEntity:[NSEntityDescription entityForName:@"Car" 
                                                       inManagedObjectContext:self.managedObjectContext]
            insertIntoManagedObjectContext:self.managedObjectContext];
    Make *make = [[Make alloc] initWithEntity:[NSEntityDescription entityForName:@"Make" 
                                                       inManagedObjectContext:self.managedObjectContext]
            insertIntoManagedObjectContext:self.managedObjectContext];
    make.name = _make;

    Model *model = [[Model alloc] initWithEntity:[NSEntityDescription entityForName:@"Model" 
                                                          inManagedObjectContext:self.managedObjectContext]
               insertIntoManagedObjectContext:self.managedObjectContext];
    model.name = _model;
    car.make = make;
    car.model = model;
    [self saveContext];
}
+1  A: 

don't create new makes and models but use those stored already in core data.

Write a controller that searches for a make and model with NSPredicate. something like this:

- (id)modelNamed:(NSString *)searchName addIfMissing:(BOOL)add {
    NSFetchRequest *request = [[[NSFetchRequest alloc] init] autorelease];
    NSEntityDescription *entity = [NSEntityDescription entityForName:self.entityName inManagedObjectContext:self.managedObjectContext];
    [request setEntity:entity];
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name == %@", searchName];
    [request setPredicate:predicate];
    NSError *error;
    NSArray *results = [self.managedObjectContext executeFetchRequest:request error:&error];
    if (!results) { 
        LogError(@"Error [%s], %@, %@", _cmd, error, [error localizedDescription]);
        return nil;
    }
    if ([results count] == 0) {
        if (add) {
            // add model with new name...
            id newModel = ...
            return newModel;
        }
        else
            return nil;
    }
    return [results objectAtIndex:0];
}
fluchtpunkt
+1  A: 

There are a few issues here.

The data model shows that the Make and Model entities each have a to-one relationship with Car. Therefore, there can be only one Car for each Make and only one Car for each Model. In other words, given that data model, Nissan can only make one Car. You probably want a to-many cars relationship in Model so that Nissan can make more than one Car. Same thing with Make so that there can be more than one Car with a given Make.

The way NSManagedObjects are inserted into the managed object context is incorrect. It should be done like this:

Car *car = [NSEntityDescription
    insertNewObjectForEntityForName:@"Car"
    inManagedObjectContext:self.managedObjectContext];

Finally, your code shows that a new Make and Model entity are created for each Car. If you are starting with the name of a Make, you probably want to search the managed object context for a Make that has a matching name. If found, just set the make relationship of the new Car to the Make entity that is already in the context. If not found, create a new Make entity and set up a relationship to that.

James Huddleston
thanks, 1 more question, if instead of creating a make, and model for a car, i read them from the existing make, and models, does it automatically assign them to the new car object while saving?
aryaxt
No, you'll still have to assign them, e.g., `car.make = existingMake`.
James Huddleston
thanks, that's what i meant
aryaxt