简体   繁体   中英

Core data relationships - Cart

I have the following core data relationship set up in my model.

Category -> Product -> CartProduct <<- Cart (See picture below).

在此处输入图片说明

But I have a hard time figuring out how to establish these relationships (in code). I have made 2 Objective-C Categories, with the names: CartProduct+Product & Cart+CartProduct.

CartProduct+Product contains the following code - this method is called, when the user pushes the "add to cart" button.

+ (CartProduct *)addProductToCartProducts:(Product *)theProduct inManagedObjectContext:(NSManagedObjectContext *)context {


CartProduct *cartProduct = nil;

NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"CartProduct"];
NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"products" ascending:YES];
request.sortDescriptors = [NSArray arrayWithObject:sortDescriptor];

NSError *error = nil;
NSArray *cartProducts = [context executeFetchRequest:request error:&error];

if (!cartProducts || ([cartProducts count] > 1)) {
    // handle error

} else if (![cartProducts count]) {




      cartProduct = [NSEntityDescription insertNewObjectForEntityForName:@"CartProduct"
                                                   inManagedObjectContext:context];
    /*This method is called from an background context, to prevent context conflicting, get nsmangedobject by its id, which is threadSafe. */
    NSManagedObjectID *retID = [theProduct objectID];


    //Setup One-One relationship from Product to CartProduct
    cartProduct.product = (Product *) [context objectWithID:retID];
  /*Call method from class Cart+CartProduct to establish to-many relationship from Cart     to CartProduct.*/
    [Cart addCartProductToCart:cartProduct inManagedObjectContext:context]; 


} else {
    cartProduct = [cartProducts lastObject];
}

return cartProduct;

}

Cart+CartProduct contains the following code:

+ (Cart *)addCartProductToCart:(CartProduct *)theCartProduct inManagedObjectContext:(NSManagedObjectContext *)context {


Cart *cart = nil;

NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"CartProduct"];
NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"productsInCart" ascending:YES];
request.sortDescriptors = [NSArray arrayWithObject:sortDescriptor];

NSError *error = nil;
NSArray *cartProducts = [context executeFetchRequest:request error:&error];

if (!cartProducts || ([cartProducts count] > 1)) {
    // handle error

} else if (![cartProducts count]) {




    cart = [NSEntityDescription insertNewObjectForEntityForName:@"Cart"
                                                inManagedObjectContext:context];


    [cart addProductsInCartObject:theCartProduct];

} else {
    cart = [cartProducts lastObject];
}

return cart; 

}

Now I want to view, the objects the user has added to his Cart, I therefore fetch from the Cart entity. But I can't figure out if the I have "connected" the relationships correct? and how to fetch the products in the cart, so I can show the products. (which is in a one-many relationship with CartProduct).

So my question is:

  1. Is the relationship established correct?

  2. How do I manage to fetch the products which is added to the cart?

NB: Earlier this year, I made the following post: Add to cart functionality - Core data and this question is based on that.

Your relationships seem mostly correct, though I think you do not even need the CartProduct entity. Core Data can handle many-to-many relationships behind the scenes. You can just have Cart have a relationship "products" and Product have the inverse relationship "inCarts". A Cart can have many Products and a Product can be in many Carts.

But anyway, you can keep it as is. The only problem is that Product's relationship "cartProduct" should be to-many (and therefore should be named "cartProducts". That is, if you want it to be possible that a product is in more than one cart. Also, be sure you have all your inverse relationships correctly defined.

Your code looks all wrong to me. It's way too complicated for achieving what you're trying to do. Core Data makes it simple. It looks like you are trying to create a new Cart and add the Product to it. You shouldn't need to do any fetching to do this. It seems like maybe you are thinking like a database. With Core Data, you do not think about modifying tables, you think about setting pointers between objects. I would do it this way:

+ (Cart *)startNewCartWithProduct:(Product *)product inManagedObjectContext:(NSManagedObjectContext *)context {
    Cart *cart = [NSEntityDescription insertNewObjectForEntityForName:@"Cart" inManagedObjectContext:context];
    CartProduct *cartProduct = [NSEntityDescription insertNewObjectForEntityForName:@"CartProduct" inManagedObjectContext:context];
    // with correct inverse relationships, automatically adds cartProduct to cart:
    cartProduct.cart = cart;
    cartProduct.product = product;
    return cart;
}

Now for your question #2. To get the products in a cart, use code like this:

+ (NSSet *)productsInCart:(Cart *)cart {
    NSMutableSet *result = [NSMutableSet setWithCapacity:[cart.productsInCart size]];
    for (CartProduct *cartProduct in cart.productsInCart)
         [result addObject:cartProduct.product];
    return result;
}

Ha det bra!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM