Hi everyone:
I had encountered an issue one of my projects, I had spent dozen of hours to find the solution, I had made some progress, but still not getting what I would like to achieve ideally. I am still finding solutions myself now, while I would really appreciate anyone could share any insight for constructive solutions.
Issue:
How to add a target NSManagedObject from a master list as one object of the references in another NSManagedObject with an inverse many-to-many relationship between each NSManagedObject without creating duplicate target NSManagedObject in the master list.
Note:
The following example used an analogy to the full data model graphs to my real project. The analogy is what I can best describe the issue I have, while the objects in the analogy do not fully share the same name of the objects in the real project.
What I have now:
- A master list of ingredient objects, which are unique among each other.
- A list of recipe objects, each of which would like to have different ingredient objects to define the recipe object.
What do I want to achieve:
- Ingredient objects can be inserted as multiple times into a single recipe object with each insert as unique count instead of making same ingredient being considered as one single count.
- I did not want to duplicate each ingredient object inside of the master list to be able to add multiple ingredients objects to each recipe object or cross multiple recipe objects.
What I had tried:
- Use Core Data to manage the ingredient and recipe as 2 NSManagedObjects.
- Had created a relationship attributes called “allHostRecipes” on the ingredient managed object, and set it as “to-Many“ relationship to the recipe managed object
- Had created a relationship attributes called “allUsedIngredients” on the recipe managed object, and set it as “to-Many“ relationship to the ingredient managed object
- These two relationships are set as “inverse”.
- I had a Recipe Description View with a Table View that lists all the ingredients that are and will be included inside of the recipe.
- I created another Ingredients Selection Table View that can be triggered in the recipe description view to pick each ingredient, which is going to be added into the recipe.
- Each time when an ingredient is picked in the Ingredients Selection Table View, I call objectAtIndexPath(_:) on the NSFetchedResultsController that is for ingredients Table View from the ingredients’ master list to find the selected ingredient objects in its ManagedObjectContext.
- Then I passed the selected ingredient managed object (SelectedIngredientManagedObject) back to Recipe Description View and called mutableSetValueForKey("allUsedIngredients").addObject(SelectedIngredientManagedObject) on the NSFetchedResultsController that is for fetching ingredients that is contained inside of a recipe object.
- The “NSFetchedResultsController that is for ingredients Table View from the ingredients’ master list” and “NSFetchedResultsController that is for fetching ingredients that are contained inside of a recipe object” are separate instance variables in “Table Views of Recipe Description View” and “Ingredients Selection Table View”. But they referenced the same ManagedObjectContext.
What I had got now:
- The selected ingredient managed object can be added to the recipe.
- But, if I selected the same ingredient multiple times, it only get count once in the Table Views of Recipe Description View instead of showing multiple counts by each inserting, which is NOT what I want to achieve as described above.
My Question:
What should I do or adjust to achieve the functionalities that I had to describe above?
What I think the directions to solve the issue:
- What other things should I do when defining the “Many-to-Many” relationship in Core Data model?
- Does the fact that the “to-Many“ reference is using an NSSet cause the count issue?
- Is it necessary to create multiple ManagedObjectContext to achieve the desired functionalities?
- Should I clone the selected ingredient managed object as a new ingredient managed object? Which I had tried, and it will add duplicated ingredient to the ingredients’ master list. This is also NOT what I want. If I need to clone it, how can I make it right?
I really appreciate your time to view it, I am looking forward to having your insights. Thank you very much.
Regards,
Knight
Solution:
The same issue had been posted at stack overflow, and here is the discussion and solution of it.
http://stackoverflow.com/questions/39016828/how-to-add-target-nsmanagedobject-to-another-one-with-an-inverse-many-to-many-co
Generally, the project needs to create an intermediate (join) entity to keep track of the relationships between recipe and ingredients objects, which follows the guide in "Modeling a Relationship Based on Its Semantics" section of the document "Core Data Programming Guide - Creating Managed Object Relationships":
Thank you.